vector<vector<int>> cluster(vector<Segment> &D, double epsilon, int minlns){
	Segment L;
	vector<int> clus(D.size());
	fill(clus.begin(), clus.end(),-1);
	vector<int> temp_neigh;
	progress::begin();
	int clusterId = 0;
	for (int i = 0; i<D.size(); i++){
		progress::step("clustering: ", i, 1, D.size());
		if (clus[i]==-1){
			temp_neigh = neighborhood(D, i, epsilon);
			if(temp_neigh.size()>= minlns){
				clus[i]=clusterId;
				queue<int> Q;
				for(auto j : temp_neigh){
					clus[j]= clusterId;
					Q.push(j);
				}
				expandCluster(D, clus, Q, clusterId, epsilon, minlns);
				clusterId++;
			}
			else{
				clus[i]=-2;
			}
		}
	}
	progress::done();
	//collect and clean the clusters
	vector<vector<int>> ret(clusterId);
	vector<unordered_set<int>> participating(clusterId);
	for(int i = 0; i<clus.size(); i++){
		if (clus[i]>=0){
			ret[clus[i]].push_back(i);
			D[i].myclus = clus[i];
			participating[clus[i]].insert(D[i].mytraj);
		}
	}
	for(int i = 0; i<participating.size(); i++){
		if (participating[i].size()<=minlns){
			participating.erase(participating.begin() + i);
			ret.erase(ret.begin() + i);
			i--;
		}
	}
	sort(ret.begin(), ret.end(), cs);
	return ret;
}
Ejemplo n.º 2
0
	void run() {
		// Do some validation of the arguments
		if (graph.rows() != graph.cols()) {
			throw std::invalid_argument("Matrix must be square");
		}
		if (graph.any_element_is_inf_or_nan()) {
			throw std::invalid_argument("Matrix includes Inf or NaN values");
		}
		if (graph.any_element_is_negative()) {
			throw std::invalid_argument("Matrix includes negative values");
		}
		if (!is_symmetric(graph)) {
			throw std::invalid_argument("Matrix must be symmetric");
		}
		if (!clustering.empty() && (int)clustering.size() != graph.rows()) {
			throw std::invalid_argument("Initial value must have same size as the matrix");
		}
		
		// initialize Clustering object
		params.lossfun = lossfun.get();
		srand(seed);
		Clustering clus(graph,params);
		if (!clustering.empty()) {
			clus.set_clustering(clustering);
		}
		
		// perform clustering
		if (optimize) {
			clus.optimize();
		}
		
		// outputs
		clustering = clus.get_clustering();
		loss = clus.get_loss();
		num_clusters = clus.num_clusters();
	}
// CLUSTERING METHOD
std::vector<poseEstimationSI::clusterPtr> poseEstimationSI::poseClustering(std::vector < posePtr > & bestPoses)
{
	// Sort clusters
	std::sort(bestPoses.begin(), bestPoses.end(), pose::compare);

	std::vector< boost::shared_ptr<poseCluster> > centroids;
	std::vector< boost::shared_ptr<cluster> > transformations;    

	float _orientationDistance;	
	float _positionDistance;
	float _scaleDistance;

	bool found;
	
	int nearestCentroid;

	///////////////////////////////
	// Initialize first centroid //
	///////////////////////////////

	// If there are no poses, return
	if(bestPoses.empty())
		return transformations;


	centroids.push_back(boost::shared_ptr<poseCluster> (new poseCluster(0,bestPoses[0])));
	//centroids.back()->poses.push_back(bestPoses[0]);

	Tic();	
	// For each pose
	for(size_t p=1; p< bestPoses.size(); ++p)
	{
		found=false;
		for(size_t c=0; c < centroids.size(); ++c)
		{
			//std::cout << std::endl << "\tcheck if centroid:" << std::endl;
			// Compute (squared) distance to the cluster center
			_orientationDistance=orientationDistance(bestPoses[p],bestPoses[centroids[c]->poseIndex]);
			_positionDistance=positionDistance(bestPoses[p],bestPoses[centroids[c]->poseIndex]);
			_scaleDistance=scaleDistance(bestPoses[p],bestPoses[centroids[c]->poseIndex]);
			// If the cluster is nearer than a threshold add current pose to the cluster
			//if((_orientationDistance>=poseAngleStepCos) && _positionDistance<=((model->maxModelDistSquared)*0.05*0.05))
			//if((_orientationDistance>=cos(acos(poseAngleStepCos)) ) && _positionDistance<=((model->maxModelDistSquared)*0.1*0.1))
			if((_orientationDistance>=pointPair::angleStepCos) && (_positionDistance<=model->halfDistanceStepSquared) &&(equalFloat(_scaleDistance,0.0))) // VER ISTO
			{

				nearestCentroid=c;
				found=true;
				break;
			}		
		}			
			
		if(found)
		{
			centroids[nearestCentroid]->update(bestPoses[p]);
		}
		else
		{
			boost::shared_ptr<poseCluster> clus(new poseCluster(p,bestPoses[p]));
			centroids.push_back(clus);
		}
	}
	Tac();	

	//////////////////////
	// Compute clusters //
	//////////////////////
	std::sort(centroids.begin(), centroids.end(), poseCluster::compare);
	//std::cout << std::endl << "Number of poses:" <<bestPoses.size() << std::endl << std::endl;
	//std::cout << std::endl << "Best pose votes:" <<bestPoses[0]->votes << std::endl << std::endl;
	//for(size_t c=0; c < centroids.size(); ++c)
	if(filterOn)
	{
		for(size_t c=0; c < centroids.size(); ++c)
		//for(size_t c=0; c < 1; ++c)
		{
			//std::cout << centroids[c]->votes << std::endl;
			transformations.push_back(boost::shared_ptr<cluster> (new cluster( boost::shared_ptr<pose> (new pose (centroids[c]->votes, boost::shared_ptr<transformation>( new transformation(centroids[c]->rotation(),centroids[c]->translation(),centroids[c]->scaling() ) ) ) ),centroids[c]->poses ) ) );
		}
	}
	else
	{
		transformations.push_back(boost::shared_ptr<cluster> (new cluster( boost::shared_ptr<pose> (new pose (centroids[0]->votes, boost::shared_ptr<transformation>( new transformation(centroids[0]->rotation(),centroids[0]->translation(),centroids[0]->scaling() ) ) ) ),centroids[0]->poses ) ) );
	}

	return transformations;
}