代码没错,但无法运行出来运行
c吧
全部回复
仅看楼主
level 1
chansyway 楼主
代码没有错误,能运行一部分,但在人工输入数据时无法输入,出现错误,这是怎么回事
#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;
}
2015年05月09日 04点05分 1
1