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; }
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; }