void MultiLabelTree::DirectSplit(CBranch* node) {
    vector<vector<float>> pos;
	vector<vector<float>> value;
	for (int i = 0; i < node->linked_nodes.size(); ++i) {
		pos.push_back(node->linked_nodes[i]->mean_pos);
		value.push_back(node->linked_nodes[i]->mean_values);
	}

    vector<int> clusters;
    //float child_radius = min((node->right - node->left), (node->top - node->bottom)) / 2;
    //float child_radius = ((node->right - node->left) + (node->top - node->bottom)) / 4;
    //float child_radius = node->radius / factor_;
    float child_radius = sqrt((node->right - node->left) * (node->top - node->bottom) / EXPECTED_CLUSTER_NUM);
    SplitPoints(pos, value, child_radius, clusters);

    vector<CBranch*> label_nodes;
	label_nodes.resize(node->linked_nodes.size(), NULL);
	for (int i = 0; i < clusters.size(); ++i) {
		int label = clusters[i];
		if (label < 0) continue;
		if (label_nodes[label] == NULL) {
			label_nodes[label] = new CBranch;
			label_nodes[label]->set_level(node->level() + 1);
			label_nodes[label]->radius = child_radius;
			label_nodes[label]->parent = node;
		}
		label_nodes[label]->linked_nodes.push_back(node->linked_nodes[i]);
		node->linked_nodes[i]->set_level(node->level() + 2);
		node->linked_nodes[i]->parent = label_nodes[label];
	}

	vector<CNode*> linked_nodes;
	for (int i = 0; i < clusters.size(); ++i)
		if (label_nodes[i] != NULL) {
			linked_nodes.push_back(label_nodes[i]);
		}
	for (int i = 0; i < linked_nodes.size(); ++i)
		ProgressNodeData(linked_nodes[i]);

	vector<int> tour_list;
	TourPathGenerator::GenerateRoundPath(linked_nodes, tour_list);
	node->linked_nodes.clear();
	for (int i = 0; i < tour_list.size(); ++i)
		node->linked_nodes.push_back(linked_nodes[tour_list[i]]);
}
예제 #2
0
void SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
    SplitNode(arma::Col<size_t>& points,
              const size_t maxLeafSize,
              const double tau,
              const double rho)
{
  // We need to expand the bounds of this node properly.
  for (size_t i = 0; i < points.n_elem; i++)
    bound |= dataset->col(points[i]);

  // Calculate the furthest descendant distance.
  furthestDescendantDistance = 0.5 * bound.Diameter();

  // Now, check if we need to split at all.
  if (points.n_elem <= maxLeafSize)
  {
    pointsIndex = new arma::Col<size_t>();
    pointsIndex->swap(points);
    count = pointsIndex->n_elem;
    return; // We can't split this.
  }

  const bool split = SplitType<MetricType, MatType>::SplitSpace(bound,
      *dataset, points, hyperplane);
  // The node may not be always split. For instance, if all the points are the
  // same, we can't split them.
  if (!split)
  {
    pointsIndex = new arma::Col<size_t>();
    pointsIndex->swap(points);
    count = pointsIndex->n_elem;
    return; // We can't split this.
  }

  arma::Col<size_t> leftPoints, rightPoints;
  // Split the node.
  overlappingNode = SplitPoints(tau, rho, points, leftPoints, rightPoints);

  // We don't need the information in points, so lets clean it.
  arma::Col<size_t>().swap(points);

  // Now we will recursively split the children by calling their constructors
  // (which perform this splitting process).
  left = new SpillTree(this, leftPoints, tau, maxLeafSize, rho);
  right = new SpillTree(this, rightPoints, tau, maxLeafSize, rho);

  // Update count number, to represent the number of descendant points.
  count = left->NumDescendants() + right->NumDescendants();

  // Calculate parent distances for those two nodes.
  arma::vec center, leftCenter, rightCenter;
  Center(center);
  left->Center(leftCenter);
  right->Center(rightCenter);

  const ElemType leftParentDistance = MetricType::Evaluate(center, leftCenter);
  const ElemType rightParentDistance = MetricType::Evaluate(center,
      rightCenter);

  left->ParentDistance() = leftParentDistance;
  right->ParentDistance() = rightParentDistance;
}
void MultiLabelTree::SplitOnSlic(CBranch* node) {
    vector<vector<float>> pos;
	vector<vector<float>> value;
	for (int i = 0; i < node->linked_nodes.size(); ++i) {
		pos.push_back(node->linked_nodes[i]->mean_pos);
		value.push_back(node->linked_nodes[i]->mean_values);
	}

    vector<vector<vector<float>>> pixel_data;
    vector<vector<int>> node_count;
    int imw = (int)sqrt(node->linked_nodes.size()), imh = 200;
    imh = (node->top - node->bottom) / (node->right - node->left) * imw;
    while (imw * imh < 16 * SLIC_PIXEL_THRESHOLD) {
        imh *= 2;
        imw *= 2;
    }

    pixel_data.resize(imh);
    node_count.resize(imh);
    for (int i = 0; i < imh; ++i) {
        pixel_data[i].resize(imw);
        node_count[i].resize(imw, 0);
        for (int j = 0; j < imw; ++j)
            pixel_data[i][j].resize(point_dataset_->var_num, 0);
    }

    float node_width = node->right - node->left;
    float node_height = node->top - node->bottom;
    for (int i = 0; i < pos.size(); i++) {
        int xi = (int)((pos[i][0] - node->left) / node_width * (imw - 1));
        int yi = (int)((pos[i][1] - node->bottom) / node_height * (imh - 1));
        node_count[yi][xi]++;
        for (int j = 0; j < point_dataset_->var_num; j++)
            pixel_data[yi][xi][j] += value[i][j];
    }

        
    for (int i = 0; i < imh; ++i)
        for (int j = 0; j < imw; ++j)
            if (node_count[i][j] != 0) {
                for (int k = 0; k < point_dataset_->var_num; ++k)
                    pixel_data[i][j][k] /= node_count[i][j];
            }

    VectorFieldData* vfd = new VectorFieldData(pixel_data);

    double step = sqrt(imw * imh / (double)SLIC_PIXEL_THRESHOLD);
    int nc = 1.0;

    Slic slic;
    slic.GenerateSuperPixels(vfd, step, nc);
    vector<vector<int>>& spixel_index = slic.GetClusters();
    vector<vector<float>>& spixel_centers = slic.GetCenters();
    vector<int> spixel_count;
    spixel_count.resize(spixel_centers.size(), 0);
    for (int i = 0; i < imh; ++i)
        for (int j = 0; j < imw; ++j) 
            spixel_count[spixel_index[j][i]] += node_count[i][j];

    vector<vector<float>> new_pos;
    vector<vector<float>> new_value;
    vector<int> spixel_to_node_index;

    float scale_rate = node->right - node->left;
    for (int i = 0; i < spixel_count.size(); ++i)
        if (spixel_count[i] != 0) {
            new_pos.push_back(vector<float>{spixel_centers[i][0] / (imw - 1) * scale_rate, spixel_centers[i][1] / (imh - 1) * scale_rate});
            vector<float> temp_value;
            for (int j = 2; j < spixel_centers[i].size(); ++j)
                temp_value.push_back(spixel_centers[i][j]);
            new_value.push_back(temp_value);
            spixel_to_node_index.push_back(new_pos.size() - 1);
        }
        else {
            spixel_to_node_index.push_back(-1);
        }


    vector<int> clusters;
    //float child_radius = max((node->right - node->left), (node->top - node->bottom)) / 2;
    //float child_radius = ((node->right - node->left) + (node->top - node->bottom)) / 4;
    //float child_radius = node->radius / factor_;
    float child_radius = sqrt((node->right - node->left) * (node->top - node->bottom) / EXPECTED_CLUSTER_NUM);
    SplitPoints(new_pos, new_value, child_radius, clusters);

    vector<CBranch*> label_nodes;
	label_nodes.resize(clusters.size(), NULL);
    for (int i = 0; i < pos.size(); i++) {
        int xi = (int)((pos[i][0] - node->left) / node_width * (imw - 1));
        int yi = (int)((pos[i][1] - node->bottom) / node_height * (imh - 1));
        int label = clusters[spixel_to_node_index[spixel_index[xi][yi]]];

        if (label_nodes[label] == NULL) {
			label_nodes[label] = new CBranch;
			label_nodes[label]->set_level(node->level() + 1);
			label_nodes[label]->radius = child_radius;
			label_nodes[label]->parent = node;
		}

		label_nodes[label]->linked_nodes.push_back(node->linked_nodes[i]);
		node->linked_nodes[i]->set_level(node->level() + 2);
		node->linked_nodes[i]->parent = label_nodes[label];
    }

	vector<CNode*> linked_nodes;
	for (int i = 0; i < clusters.size(); ++i)
		if (label_nodes[i] != NULL) {
			linked_nodes.push_back(label_nodes[i]);
		}
	for (int i = 0; i < linked_nodes.size(); ++i)
		ProgressNodeData(linked_nodes[i]);

	vector<int> tour_list;
	TourPathGenerator::GenerateRoundPath(linked_nodes, tour_list);
	node->linked_nodes.clear();
	for (int i = 0; i < tour_list.size(); ++i)
		node->linked_nodes.push_back(linked_nodes[tour_list[i]]);
}