chansyway chansyway
关注数: 3 粉丝数: 14 发帖数: 87 关注贴吧数: 15
代码没错,但无法运行出来运行 代码没有错误,能运行一部分,但在人工输入数据时无法输入,出现错误,这是怎么回事 #include "iostream" # include "math.h" # include "stdlib.h" #include<iomanip> # include "time.h" # include "fstream" using std::cout; using std::endl; using std::cin; using std::setw; using namespace std; // * * * * * * * * * * * 定义常量 const int TRUE = 1; const int FALSE = 0; const long MAX = 100000; const int AcceptRate = 1; const double ForceDecline = 0.9; // * * * * * * * * * * * 定义变量 int DataNum; //聚类样本数目 int Dimension; //样本维数 int K; //分类数 double * DataSet; //指向浮点型的指针 int HALT = 0; int Row = 3; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // GETDATA类:定义维数,样本数,和类别数等 *** // 选择随机生成样本或手工输入样本的类 ** // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * class GETDATA { public: GETDATA(); void Display(); void Initial(); void Input(); double FRand(double, double); double rand1, rand2; //随机数的高低值 }; GETDATA::GETDATA() //构造函数 { int i, j; Dimension = 2; DataNum = 50; K = 4; DataSet = new double[Dimension * DataNum]; for(i = 0; i < DataNum; i++) { for(j = 0;j<Dimension;j++) DataSet[i* Dimension + j] = (((double)rand() / (double) RAND_MAX) * 100); } } // * * * * * * * * * * * 显示待聚类的样本 void GETDATA::Display() { int i, j; cout << " 当前样本集如下 : " << endl << " { " << endl; for (i = 0; i< DataNum; i++) { cout << " [ "; for(j = 0; j < Dimension; j++) { cout << " " <<setw(8)<< DataSet[i* Dimension+j]; } cout << " ] "; if((i + 1) % Row == 0) cout << endl; } cout << endl << " } " << endl; cout << endl << "以上实数样本集由计算机在---100之间随机产,其中:" <<endl ; cout << endl << " 样本维数 Dimension = " << Dimension << endl; cout << " 样本数 DataNum = " << DataNum << endl; cout << " 类别数 K = " << K << endl; } // * * * * * * * * * * * 输入待聚类样本,包括维数,个数,类别数等 void GETDATA::Input() { char flag; int I, j; double s = 0; cout << endl << " 请依次输入: 维数 样本数目 类别数 " << endl; cout << endl << " 维数 Dimension : "; cin >> Dimension; cout << endl << " 样本数目 DataNum : "; cin >> DataNum; cout << endl << " 类别数 K : "; cin >> K; cout << endl << " 随机生成数据输入 R 人工输入按 B : " << endl; delete[] DataSet; DataSet = new double[Dimension * DataNum]; cin >> flag; if(flag== 'R' || flag == 'r') { cout << " 输入随机数生成范围 ( 最小值和最大值 ) : " << endl << " 最小值 : "; cin >> rand1; cout << endl << " 最大值 : "; cin >> rand2; for(int i= 0; i< DataNum; i++) { for(j = 0; j < Dimension; j ++) DataSet[i* Dimension + j] = FRand(rand1, rand2); } } else if (flag == 'H' || flag == 'h') { for(I = 0; I < DataNum; I ++) { cout << endl << " 请输入第 " << I + 1 << " 个样本的" << Dimension << " 个分量 "; for(j = 0; j < Dimension; j ++) cin >> DataSet[I * Dimension + j]; } } else cout << endl << " 非法数据 ! "; } // * * * * * * * * * * *初始化样本 void GETDATA::Initial() { char ch; GETDATA::Display(); cout << endl << " 重新录入样本输入A 开始聚类B : "; cin >> ch; while(!(ch == 'A' || ch == 'a')&&!(ch == 'B' || ch == 'b')) { cout << endl << " 重新录入样本输入A 开始聚类B: "; cin >> ch; } if(ch == 'A' || ch == 'a') GETDATA::Input(); } double GETDATA::FRand(double rand1, double rand2) { return rand1 + (double)(((double)rand() / (double)RAND_MAX) * (rand2 - rand1)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 类SSA: K-均值算法的实现 *** //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * class SAA { public: struct DataType { double * data; int father; double * uncle; }; struct ClusterType { double * center; int sonnum; }; SAA(); void Initialize(); void KMeans(); void SA(); void DisPlay(); void GetDataset(DataType * p1, double * p2, int datanum, int dim); void GetValue(double * str1, double * str2, int dim); int DisFather(double *p, int k); double SquareDistance(double * str1, double * str2, int dim); int Comqare(double * p1, double * p2, int dim); void NewCenterPlus(ClusterType * p1, int t, double * p2, int dim); void NewCenterReduce(ClusterType * p1, int t, double * p2, int dim); double MaxFunc(); void Generate(DataType * p1, ClusterType * c1); double Comqare(DataType * p1, ClusterType * c1, DataType * p2, ClusterType * c2); void CopyStatus(DataType * p1, ClusterType * c1, DataType * p2, ClusterType * c2); int SecondFather(DataType * p, int t, int k); double AimFunction(DataType * q, ClusterType * c); double FRand(double, double); void KMeans1(); protected: double Temp; double AimFunc; DataType * DataMember, *KResult, *CurrentStatus, *NewStatus; ClusterType * ClusterMember, *NewCluster, *CurrentCluster; }; // end of class SAA // * * * * * * * * * * * *建立构造函数,初始化保护成员 SAA::SAA() { int I; DataMember = new DataType[DataNum]; ClusterMember = new ClusterType[K]; for(I = 0;I< DataNum;I++) { DataMember[I].data = new double[Dimension]; DataMember[I].uncle = new double[K]; } for(I = 0; I < K; I ++) ClusterMember[I].center = new double[Dimension]; GetDataset(DataMember, DataSet, DataNum, Dimension); } // end SAA // * * * * * * * * * * * *初始化参数,及开始搜索状态 // * * * * * * * * * * * * k - 均值法进行聚类 // * * * * * * * * * * * *接口:数据,数量,维数,类别 // * * * * * * * * * * * *逐点聚类方式 void SAA::KMeans() { int I, j, M = 1; int qa, qb, fa; ClusterType * Cluster; // 初始化聚类中心 Cluster = new ClusterType[K]; for(I =0;I < K; I++) { cout << endl << I + 1 << " 中心 : " ; GetValue(ClusterMember[I].center, DataMember[I].data, Dimension); ClusterMember[I].sonnum = 1; Cluster[I].center = new double[Dimension]; GetValue(Cluster[I].center, ClusterMember[I].center, Dimension); } for(I = 0; I < DataNum; I ++) { // cout << endl << I + 1 << " : " << ClusterMember [ 0 ] . center [ 0 ] << " " << ClusterMember[1].center[0] << " son : " << ClusterMember[0] .sonnum; for(j = 0; j < K; j ++) { DataMember[I].uncle[j] = SquareDistance(DataMember[I] . data, ClusterMember[j].center, Dimension); cout << " " << I + 1 << " -> " << j + 1 << " : " << DataMember [I].uncle[j] <<" 类中心 " << ClusterMember [ j ] . center [ 0 ] << " : " << DataMember[I].uncle[j] << " "; } qa = DataMember[I].father = DisFather(DataMember[I].uncle, K); if(I >= K) { cout << endl << qa << " 类样本数 : " << ClusterMember [ qa ] . sonnum;ClusterMember[qa].sonnum += 1; cout << endl << qa << " 类样本数 : " << ClusterMember [ qa ] . sonnum; NewCenterPlus(ClusterMember, qa, DataMember[I].data, Dimension); cout << endl << I + 1 << " -> " << qa + 1 << "类 : " << ClusterMember[qa].center[0];GetValue(Cluster[qa].center, ClusterMember[qa].center,Dimension); } } //开始聚类,直到聚类中心不再发生变化。××逐个修改法×× while(!HALT) { // 一次聚类循环:.重新归类;.修改类中心 for(I = 0; I < DataNum; I++) { cout<<endl; for (j = 0; j<K; j++) { cout<<" D " << DataMember [ I ] . data [ 0 ] << " " << ClusterMember[j].center[0] << " ";DataMember[I].uncle[j] = SquareDistance(DataMember[I] .data, ClusterMember[j].center, Dimension); cout << DataMember [ I ] . data [ 0 ] << " -> " << ClusterMember[0l].center[0] << " : " << DataMember[I].uncle[0] << endl; cout << I + 1 << " -> " << j + 1 << " " << DataMember [ I ] .uncle [j]; } fa = DataMember[I].father; if(fa != DisFather(DataMember[I].uncle, K) && ClusterMember[fa].sonnum > 1) { qa = DataMember[I].father; ClusterMember[qa].sonnum -= 1; qb = DataMember[I].father = DisFather(DataMember[I] . uncle, K); ClusterMember[qb].sonnum += 1; NewCenterReduce(ClusterMember, qa, DataMember[I].data, Dimension); NewCenterPlus(ClusterMember, qb, DataMember[I].data, Dimension); cout << endl << "* * * * * * * * * * * * "<< M << "次聚类 :* * * * * * * * * * * * * * * " ; // 聚一次类输出一次结果 cout << endl << DataMember [ I ] . data [ 0 ] << " in "<<qa+1<<"类-> " << qb+1 << " 类 : " ; for ( int t = 0 ; t < K ; t ++ ) { cout << endl << " 第 "<< t + 1 << " 类中心 : " << ClusterMember [ t ] . center [ 0 ] << " 样本个数 : " << ClusterMember[ t ] .sonnum ; } DisPlay ( ) ; M = M + 1 ; } } // endfor // 判断聚类是否完成,HALT=1,停止聚类 HALT = 0; for(j =0; j < K; j++) if (Comqare(Cluster[j].center, ClusterMember[j].center, Dimension)) break; if (j == K) HALT = 1; for(j = 0; j < K; j ++) GetValue(Cluster[j].center, ClusterMember[j].center, Dimension); } // end while } // end of K - Means // 批聚类方式 void SAA::KMeans1() { int I, j, M = 1; int qa, qb, fa; ClusterType * Cluster; // 初始化聚类中心 Cluster = new ClusterType[K]; for(I = 0; I < K; I++) Cluster[I].center = new double[Dimension]; for(j = 0; j < K; j++) GetValue(Cluster[j].center, ClusterMember[j].center, Dimension); // 开始聚类,直到聚类中心不再发生变化。××逐个修改法×× while(!HALT) { // 一次聚类循环:.重新归类;.修改类中心 for(I = 0; I < DataNum; I ++) { for(j = 0; j < K; j ++) DataMember[I].uncle[j] = SquareDistance(DataMember[I] . data, ClusterMember[j].center, Dimension); fa = DataMember[I].father; if(fa != DisFather(DataMember[I].uncle, K) && ClusterMember[fa].sonnum > 1) { qa = DataMember[I].father; ClusterMember[qa].sonnum -= 1; qb = DataMember[I].father = DisFather(DataMember[I] . uncle, K); ClusterMember[qb].sonnum += 1; NewCenterReduce(ClusterMember, qa, DataMember[I].data, Dimension); NewCenterPlus(ClusterMember, qb, DataMember[I].data, Dimension); } } // end for // 判断聚类是否完成,HALT=1,停止聚类 HALT = 0; for (j = 0; j < K; j ++) if (Comqare(Cluster[j].center, ClusterMember[j].center, Dimension)) break; if (j == K) HALT = 1; for(j = 0;j < K; j ++) GetValue(Cluster[j].center, ClusterMember[j].center, Dimension); } // end while } // 几个经常需要调用的小函数 void SAA::NewCenterPlus(ClusterType * p1, int t, double * p2, int dim) { int I; for (I = 0; I < dim; I ++) p1[t].center[I] = p1[t].center[I] + (p2[I] - p1[t].center[I]) / (p1 [t].sonnum); } void SAA::NewCenterReduce(ClusterType * p1, int t, double * p2, int dim) { int I; for (I = 0; I < dim; I++) p1[t].center[I] = p1[t].center[I] + (p1[t].center[I] - p2[I] /(p1[t].sonnum)); } void SAA::GetDataset(DataType * p1, double * p2, int datanum, int dim) { int I, j; for (I = 0; I < datanum; I ++) { for(j = 0;j < dim; j ++) p1[I].data[j] = p2[I * dim + j]; } } void SAA::GetValue(double * str1, double * str2, int dim) { int I; for (I = 0; I < dim; I ++) str1[I] = str2[I]; } int SAA::DisFather(double *p, int k) { int I, N = 0; double min = 30000; for (I = 0; I < k; I ++) if (p[I] < min) { min = p[I]; N = I; } return N; } double SAA::SquareDistance(double * str1, double * str2, int dim) { double dis = 0; int I; for (I = 0; I < dim; I ++) dis = dis + (double)(str1[I] - str2[I]) * (str1[I] - str2[I]); return dis; } int SAA::Comqare(double * p1, double * p2, int dim) { int I; for (I = 0; I < dim; I ++) if (p1[I]!= p2[I]) return 1; return 0; } double SAA::FRand(double a, double b) { return a + (double)(((double)rand() / (double)RAND_MAX) * (b-a)); } void SAA::DisPlay() { int I, N, j, t; ofstream result(" 聚类过程结果显示 . txt ", ios::ate); for (I = 0; I < K; I ++) { N = 0; cout << endl << endl << " * * * * * * * * * * * *第" << I + 1 << " 类样本 : * * * * * * * * * * * * " << endl ; result << endl << endl << " * * * * * * * * * * * *第" << I + 1 << " 类样本: * * * * * * * * * * * * " << endl ; for(j = 0; j < DataNum; j ++) if(DataMember[j].father == I) { cout << " [ "; for(t = 0; t < Dimension; t ++) cout << " " << setw(5) << DataMember[j].data[t]; cout << " ] "; if((N + 1) % Row == 0) cout << endl; result << " ["; for(t = 0; t < Dimension; t ++) result << " " << setw(5) << DataMember[j].data[t]; result << " ] "; if((N + 1) % Row == 0) result << endl; N = N + 1; } } // end for cout << endl << endl << " 聚类结果,总体误差准则函数:" << AimFunction(DataMember, ClusterMember) << endl; result << endl << " 聚类结果,总体误差准则函数:" << AimFunction (DataMember, ClusterMember) << endl; result.close(); } // end of Display double SAA::AimFunction(DataType * q, ClusterType * c) { int I, j; double * p; p = new double[K]; for (I = 0; I < K; I ++) p[I] = 0; for (I = 0; I < K; I ++) { for(j = 0; j < DataNum; j ++) if(q[j].father == I) { p[I] = p[I] + SquareDistance(c[I].center, q[j].data,Dimension); } } AimFunc = 0; for(I = 0; I < K; I ++) AimFunc = AimFunc + p[I]; return AimFunc; } void main() //主函数 { // 用户输入数据 srand((unsigned)time(NULL)); GETDATA getdata; getdata.Initial(); ofstream file(" 聚类过程结果显示 .txt ", ios::trunc); //聚类结果存入“聚类结果显示.txt”文件中 //k-均值聚类方法聚类 SAA saa; //****此行不可与上行互换。 saa.KMeans(); //逐个样本聚类 saa . KMeans1 ( ) ; //批处理方式聚类,可以比较saa.KMeans()的区别 cout << endl << " * * * * * * * * * * * * * K-均值聚类结果:* * * * * * * * * * * * * * * * *"; file << endl << " * * * * * * * * * * * * * K-均值聚类结果:* * * * * * * * * * * * * * * * *"; file.close(); saa.DisPlay(); cout << endl << " 程序运行结束!" << endl; }
代码没错,但无法运行出来运行 代码没有错误,能运行一部分,但在人工输入数据时无法输入,出现错误,这是怎么回事 #include "iostream" # include "math.h" # include "stdlib.h" #include<iomanip> # include "time.h" # include "fstream" using std::cout; using std::endl; using std::cin; using std::setw; using namespace std; // * * * * * * * * * * * 定义常量 const int TRUE = 1; const int FALSE = 0; const long MAX = 100000; const int AcceptRate = 1; const double ForceDecline = 0.9; // * * * * * * * * * * * 定义变量 int DataNum; //聚类样本数目 int Dimension; //样本维数 int K; //分类数 double * DataSet; //指向浮点型的指针 int HALT = 0; int Row = 3; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // GETDATA类:定义维数,样本数,和类别数等 *** // 选择随机生成样本或手工输入样本的类 ** // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * class GETDATA { public: GETDATA(); void Display(); void Initial(); void Input(); double FRand(double, double); double rand1, rand2; //随机数的高低值 }; GETDATA::GETDATA() //构造函数 { int i, j; Dimension = 2; DataNum = 50; K = 4; DataSet = new double[Dimension * DataNum]; for(i = 0; i < DataNum; i++) { for(j = 0;j<Dimension;j++) DataSet[i* Dimension + j] = (((double)rand() / (double) RAND_MAX) * 100); } } // * * * * * * * * * * * 显示待聚类的样本 void GETDATA::Display() { int i, j; cout << " 当前样本集如下 : " << endl << " { " << endl; for (i = 0; i< DataNum; i++) { cout << " [ "; for(j = 0; j < Dimension; j++) { cout << " " <<setw(8)<< DataSet[i* Dimension+j]; } cout << " ] "; if((i + 1) % Row == 0) cout << endl; } cout << endl << " } " << endl; cout << endl << "以上实数样本集由计算机在---100之间随机产,其中:" <<endl ; cout << endl << " 样本维数 Dimension = " << Dimension << endl; cout << " 样本数 DataNum = " << DataNum << endl; cout << " 类别数 K = " << K << endl; } // * * * * * * * * * * * 输入待聚类样本,包括维数,个数,类别数等 void GETDATA::Input() { char flag; int I, j; double s = 0; cout << endl << " 请依次输入: 维数 样本数目 类别数 " << endl; cout << endl << " 维数 Dimension : "; cin >> Dimension; cout << endl << " 样本数目 DataNum : "; cin >> DataNum; cout << endl << " 类别数 K : "; cin >> K; cout << endl << " 随机生成数据输入 R 人工输入按 B : " << endl; delete[] DataSet; DataSet = new double[Dimension * DataNum]; cin >> flag; if(flag== 'R' || flag == 'r') { cout << " 输入随机数生成范围 ( 最小值和最大值 ) : " << endl << " 最小值 : "; cin >> rand1; cout << endl << " 最大值 : "; cin >> rand2; for(int i= 0; i< DataNum; i++) { for(j = 0; j < Dimension; j ++) DataSet[i* Dimension + j] = FRand(rand1, rand2); } } else if (flag == 'H' || flag == 'h') { for(I = 0; I < DataNum; I ++) { cout << endl << " 请输入第 " << I + 1 << " 个样本的" << Dimension << " 个分量 "; for(j = 0; j < Dimension; j ++) cin >> DataSet[I * Dimension + j]; } } else cout << endl << " 非法数据 ! "; } // * * * * * * * * * * *初始化样本 void GETDATA::Initial() { char ch; GETDATA::Display(); cout << endl << " 重新录入样本输入A 开始聚类B : "; cin >> ch; while(!(ch == 'A' || ch == 'a')&&!(ch == 'B' || ch == 'b')) { cout << endl << " 重新录入样本输入A 开始聚类B: "; cin >> ch; } if(ch == 'A' || ch == 'a') GETDATA::Input(); } double GETDATA::FRand(double rand1, double rand2) { return rand1 + (double)(((double)rand() / (double)RAND_MAX) * (rand2 - rand1)); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 类SSA: K-均值算法的实现 *** //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * class SAA { public: struct DataType { double * data; int father; double * uncle; }; struct ClusterType { double * center; int sonnum; }; SAA(); void Initialize(); void KMeans(); void SA(); void DisPlay(); void GetDataset(DataType * p1, double * p2, int datanum, int dim); void GetValue(double * str1, double * str2, int dim); int DisFather(double *p, int k); double SquareDistance(double * str1, double * str2, int dim); int Comqare(double * p1, double * p2, int dim); void NewCenterPlus(ClusterType * p1, int t, double * p2, int dim); void NewCenterReduce(ClusterType * p1, int t, double * p2, int dim); double MaxFunc(); void Generate(DataType * p1, ClusterType * c1); double Comqare(DataType * p1, ClusterType * c1, DataType * p2, ClusterType * c2); void CopyStatus(DataType * p1, ClusterType * c1, DataType * p2, ClusterType * c2); int SecondFather(DataType * p, int t, int k); double AimFunction(DataType * q, ClusterType * c); double FRand(double, double); void KMeans1(); protected: double Temp; double AimFunc; DataType * DataMember, *KResult, *CurrentStatus, *NewStatus; ClusterType * ClusterMember, *NewCluster, *CurrentCluster; }; // end of class SAA // * * * * * * * * * * * *建立构造函数,初始化保护成员 SAA::SAA() { int I; DataMember = new DataType[DataNum]; ClusterMember = new ClusterType[K]; for(I = 0;I< DataNum;I++) { DataMember[I].data = new double[Dimension]; DataMember[I].uncle = new double[K]; } for(I = 0; I < K; I ++) ClusterMember[I].center = new double[Dimension]; GetDataset(DataMember, DataSet, DataNum, Dimension); } // end SAA // * * * * * * * * * * * *初始化参数,及开始搜索状态 // * * * * * * * * * * * * k - 均值法进行聚类 // * * * * * * * * * * * *接口:数据,数量,维数,类别 // * * * * * * * * * * * *逐点聚类方式 void SAA::KMeans() { int I, j, M = 1; int qa, qb, fa; ClusterType * Cluster; // 初始化聚类中心 Cluster = new ClusterType[K]; for(I =0;I < K; I++) { cout << endl << I + 1 << " 中心 : " ; GetValue(ClusterMember[I].center, DataMember[I].data, Dimension); ClusterMember[I].sonnum = 1; Cluster[I].center = new double[Dimension]; GetValue(Cluster[I].center, ClusterMember[I].center, Dimension); } for(I = 0; I < DataNum; I ++) { // cout << endl << I + 1 << " : " << ClusterMember [ 0 ] . center [ 0 ] << " " << ClusterMember[1].center[0] << " son : " << ClusterMember[0] .sonnum; for(j = 0; j < K; j ++) { DataMember[I].uncle[j] = SquareDistance(DataMember[I] . data, ClusterMember[j].center, Dimension); cout << " " << I + 1 << " -> " << j + 1 << " : " << DataMember [I].uncle[j] <<" 类中心 " << ClusterMember [ j ] . center [ 0 ] << " : " << DataMember[I].uncle[j] << " "; } qa = DataMember[I].father = DisFather(DataMember[I].uncle, K); if(I >= K) { cout << endl << qa << " 类样本数 : " << ClusterMember [ qa ] . sonnum;ClusterMember[qa].sonnum += 1; cout << endl << qa << " 类样本数 : " << ClusterMember [ qa ] . sonnum; NewCenterPlus(ClusterMember, qa, DataMember[I].data, Dimension); cout << endl << I + 1 << " -> " << qa + 1 << "类 : " << ClusterMember[qa].center[0];GetValue(Cluster[qa].center, ClusterMember[qa].center,Dimension); } } //开始聚类,直到聚类中心不再发生变化。××逐个修改法×× while(!HALT) { // 一次聚类循环:.重新归类;.修改类中心 for(I = 0; I < DataNum; I++) { cout<<endl; for (j = 0; j<K; j++) { cout<<" D " << DataMember [ I ] . data [ 0 ] << " " << ClusterMember[j].center[0] << " ";DataMember[I].uncle[j] = SquareDistance(DataMember[I] .data, ClusterMember[j].center, Dimension); cout << DataMember [ I ] . data [ 0 ] << " -> " << ClusterMember[0l].center[0] << " : " << DataMember[I].uncle[0] << endl; cout << I + 1 << " -> " << j + 1 << " " << DataMember [ I ] .uncle [j]; } fa = DataMember[I].father; if(fa != DisFather(DataMember[I].uncle, K) && ClusterMember[fa].sonnum > 1) { qa = DataMember[I].father; ClusterMember[qa].sonnum -= 1; qb = DataMember[I].father = DisFather(DataMember[I] . uncle, K); ClusterMember[qb].sonnum += 1; NewCenterReduce(ClusterMember, qa, DataMember[I].data, Dimension); NewCenterPlus(ClusterMember, qb, DataMember[I].data, Dimension); cout << endl << "* * * * * * * * * * * * "<< M << "次聚类 :* * * * * * * * * * * * * * * " ; // 聚一次类输出一次结果 cout << endl << DataMember [ I ] . data [ 0 ] << " in "<<qa+1<<"类-> " << qb+1 << " 类 : " ; for ( int t = 0 ; t < K ; t ++ ) { cout << endl << " 第 "<< t + 1 << " 类中心 : " << ClusterMember [ t ] . center [ 0 ] << " 样本个数 : " << ClusterMember[ t ] .sonnum ; } DisPlay ( ) ; M = M + 1 ; } } // endfor // 判断聚类是否完成,HALT=1,停止聚类 HALT = 0; for(j =0; j < K; j++) if (Comqare(Cluster[j].center, ClusterMember[j].center, Dimension)) break; if (j == K) HALT = 1; for(j = 0; j < K; j ++) GetValue(Cluster[j].center, ClusterMember[j].center, Dimension); } // end while } // end of K - Means // 批聚类方式 void SAA::KMeans1() { int I, j, M = 1; int qa, qb, fa; ClusterType * Cluster; // 初始化聚类中心 Cluster = new ClusterType[K]; for(I = 0; I < K; I++) Cluster[I].center = new double[Dimension]; for(j = 0; j < K; j++) GetValue(Cluster[j].center, ClusterMember[j].center, Dimension); // 开始聚类,直到聚类中心不再发生变化。××逐个修改法×× while(!HALT) { // 一次聚类循环:.重新归类;.修改类中心 for(I = 0; I < DataNum; I ++) { for(j = 0; j < K; j ++) DataMember[I].uncle[j] = SquareDistance(DataMember[I] . data, ClusterMember[j].center, Dimension); fa = DataMember[I].father; if(fa != DisFather(DataMember[I].uncle, K) && ClusterMember[fa].sonnum > 1) { qa = DataMember[I].father; ClusterMember[qa].sonnum -= 1; qb = DataMember[I].father = DisFather(DataMember[I] . uncle, K); ClusterMember[qb].sonnum += 1; NewCenterReduce(ClusterMember, qa, DataMember[I].data, Dimension); NewCenterPlus(ClusterMember, qb, DataMember[I].data, Dimension); } } // end for // 判断聚类是否完成,HALT=1,停止聚类 HALT = 0; for (j = 0; j < K; j ++) if (Comqare(Cluster[j].center, ClusterMember[j].center, Dimension)) break; if (j == K) HALT = 1; for(j = 0;j < K; j ++) GetValue(Cluster[j].center, ClusterMember[j].center, Dimension); } // end while } // 几个经常需要调用的小函数 void SAA::NewCenterPlus(ClusterType * p1, int t, double * p2, int dim) { int I; for (I = 0; I < dim; I ++) p1[t].center[I] = p1[t].center[I] + (p2[I] - p1[t].center[I]) / (p1 [t].sonnum); } void SAA::NewCenterReduce(ClusterType * p1, int t, double * p2, int dim) { int I; for (I = 0; I < dim; I++) p1[t].center[I] = p1[t].center[I] + (p1[t].center[I] - p2[I] /(p1[t].sonnum)); } void SAA::GetDataset(DataType * p1, double * p2, int datanum, int dim) { int I, j; for (I = 0; I < datanum; I ++) { for(j = 0;j < dim; j ++) p1[I].data[j] = p2[I * dim + j]; } } void SAA::GetValue(double * str1, double * str2, int dim) { int I; for (I = 0; I < dim; I ++) str1[I] = str2[I]; } int SAA::DisFather(double *p, int k) { int I, N = 0; double min = 30000; for (I = 0; I < k; I ++) if (p[I] < min) { min = p[I]; N = I; } return N; } double SAA::SquareDistance(double * str1, double * str2, int dim) { double dis = 0; int I; for (I = 0; I < dim; I ++) dis = dis + (double)(str1[I] - str2[I]) * (str1[I] - str2[I]); return dis; } int SAA::Comqare(double * p1, double * p2, int dim) { int I; for (I = 0; I < dim; I ++) if (p1[I]!= p2[I]) return 1; return 0; } double SAA::FRand(double a, double b) { return a + (double)(((double)rand() / (double)RAND_MAX) * (b-a)); } void SAA::DisPlay() { int I, N, j, t; ofstream result(" 聚类过程结果显示 . txt ", ios::ate); for (I = 0; I < K; I ++) { N = 0; cout << endl << endl << " * * * * * * * * * * * *第" << I + 1 << " 类样本 : * * * * * * * * * * * * " << endl ; result << endl << endl << " * * * * * * * * * * * *第" << I + 1 << " 类样本: * * * * * * * * * * * * " << endl ; for(j = 0; j < DataNum; j ++) if(DataMember[j].father == I) { cout << " [ "; for(t = 0; t < Dimension; t ++) cout << " " << setw(5) << DataMember[j].data[t]; cout << " ] "; if((N + 1) % Row == 0) cout << endl; result << " ["; for(t = 0; t < Dimension; t ++) result << " " << setw(5) << DataMember[j].data[t]; result << " ] "; if((N + 1) % Row == 0) result << endl; N = N + 1; } } // end for cout << endl << endl << " 聚类结果,总体误差准则函数:" << AimFunction(DataMember, ClusterMember) << endl; result << endl << " 聚类结果,总体误差准则函数:" << AimFunction (DataMember, ClusterMember) << endl; result.close(); } // end of Display double SAA::AimFunction(DataType * q, ClusterType * c) { int I, j; double * p; p = new double[K]; for (I = 0; I < K; I ++) p[I] = 0; for (I = 0; I < K; I ++) { for(j = 0; j < DataNum; j ++) if(q[j].father == I) { p[I] = p[I] + SquareDistance(c[I].center, q[j].data,Dimension); } } AimFunc = 0; for(I = 0; I < K; I ++) AimFunc = AimFunc + p[I]; return AimFunc; } void main() //主函数 { // 用户输入数据 srand((unsigned)time(NULL)); GETDATA getdata; getdata.Initial(); ofstream file(" 聚类过程结果显示 .txt ", ios::trunc); //聚类结果存入“聚类结果显示.txt”文件中 //k-均值聚类方法聚类 SAA saa; //****此行不可与上行互换。 saa.KMeans(); //逐个样本聚类 saa . KMeans1 ( ) ; //批处理方式聚类,可以比较saa.KMeans()的区别 cout << endl << " * * * * * * * * * * * * * K-均值聚类结果:* * * * * * * * * * * * * * * * *"; file << endl << " * * * * * * * * * * * * * K-均值聚类结果:* * * * * * * * * * * * * * * * *"; file.close(); saa.DisPlay(); cout << endl << " 程序运行结束!" << endl; }
1 下一页