☰
C++代码实现MATLAB中的clusterdata函数功能
2026/10/20 11:12:53 网站建设 项目流程
#include<iostream>#include<vector>#include<cmath>#include<algorithm>#include<map>usingnamespacestd;// ---------- 并查集 ----------structUnionFind{vector<int>parent,rank_;explicitUnionFind(intn):parent(n),rank_(n,0){for(inti=0;i<n;++i)parent[i]=i;}intfind(intx){while(parent[x]!=x){parent[x]=parent[parent[x]];// 路径压缩x=parent[x];}returnx;}boolunite(intx,inty){intrx=find(x),ry=find(y);if(rx==ry)returnfalse;if(rank_[rx]<rank_[ry])swap(rx,ry);parent[ry]=rx;if(rank_[rx]==rank_[ry])++rank_[rx];returntrue;}};// ---------- clusterdata 核心 ----------// X: 数据矩阵 (n 行 d 列),maxclust: 期望的最大簇数// 返回:长度为 n 的标签向量(1-based)vector<int>clusterdata(constvector<vector<double>>&X,intmaxclust){intn=(int)X.size();if(n==0)return{};if(maxclust>=n){vector<int>labels(n);for(inti=0;i<n;++i)labels[i]=i+1;returnlabels;}// 1) 计算所有成对欧氏距离(等价于 pdist)structEdge{doubled;inti,j;};vector<Edge>edges;edges.reserve(n*(n-1)/2);for(inti=0;i<n;++i)for(intj=i+1;j<n;++j){doubles=0.0;for(size_t k=0;k<X[i].size();++k){doublediff=X[i][k]-X[j][k];s+=diff*diff;}edges.push_back({sqrt(s),i,j});}sort(edges.begin(),edges.end(),[](constEdge&a,constEdge&b){returna.d<b.d;});// 2) 单链接层次聚类 = 按边长递增执行 KruskalUnionFinduf(n);intcomponents=n;for(constauto&e:edges){if(components<=maxclust)break;if(uf.unite(e.i,e.j))--components;}// 3) 将每个点映射为 1..maxclust 的簇标签vector<int>labels(n);map<int,int>root2label;intnext_label=1;for(inti=0;i<n;++i){intr=uf.find(i);autoit=root2label.find(r);if(it==root2label.end()){root2label[r]=next_label;labels[i]=next_label;++next_label;}else{labels[i]=it->second;}}returnlabels;}// ---------- 测试 ----------intmain(){vector<vector<double>>X={{1.0,1.0},{1.5,1.5},{5.0,5.0},{5.5,5.5},{10.0,1.0},{10.5,1.5}};intmaxclust=2;vector<int>labels=clusterdata(X,maxclust);cout<<"Cluster labels (1-based):"<<endl;for(size_t i=0;i<labels.size();++i){if(i)cout<<' ';cout<<labels[i];}cout<<endl;return0;}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询