k-means欧氏距离

//***********引入库函数

#include "iostream.h"
#include "math.h"
#include "stdlib.h"
#include "iomanip.h"
#include "time.h"
#include "fstream.h"

//*************定义常量
const int TRUE=1;
const int FALSE=0;
const int MarkovLengh=10000;
const int MaxInnerLoop=10000;
const int MaxOuterLoop=60;
const double CO=0.1;
const double DeclineRate=0.95;
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{
for(j=0;jDataSet[i*Dimension+j]=(((double)rand()/(double)RAND_MAX)*100);
}
}

//*****************显示当前待聚类的样本(维数,个数,类别数等)

void GETDATA::Display()
{
int i,j;
cout<<" 当前样本集如下:"<for(i=0;i{
cout<<" [";
for(j=0;j{
cout<<" "<}
cout<<" ] ";
if((i+1)%Row==0)
cout<}
cout<
cout<
cout<cout<cin>>Dimension;
cout<cin>>DataNum;
cout<cin>>K;
cout<DataSet=new double[Dimension*DataNum];
cin>>flag;
if(flag=='R'||flag=='r')
{
cout<<" 输入随机数生成范围(最小值和最大值):"
<cin>>rand1;
cout<cin>>rand2;
for(i=0;i{
for(j=0;jDataSet[i*Dimension+j]=FRand(rand1,rand2);
}

}
else
if(flag=='H'||flag=='h')

{
for(i=0;i{
cout<for(j=0;jcin>>DataSet[i*Dimension+j];
}
}
else
cout<}

//****************初始化聚类样本

void GETDATA::Initial()
{
char ch;
GETDATA::Display();
cout<cin>>ch;
while(!(ch=='A'||ch=='a')&&!(ch=='B'||ch=='b'))
{
cout<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-均值算法的实现 ***
// 功能:根据设定的K,DataNum,Dimension等聚类 ***
//***********************************************************

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 FindFather(double *p,int k);
double SquareDistance(double *str1,double *str2,int dim);
int Compare(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 Compare(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 CO;
//double DeclineRate;
//int MarkovLengh;
//int MaxInnerLoop;
//int MaxOuterLoop;
double AimFunc;

DataType *DataMember, *KResult,*CurrentStatus,*NewStatus;
ClusterType * ClusterMember,*NewCluster,*CurrentCluster;

}; //end of class SAA



//************建立构造函数,初始化保护成员
SAA::SAA()
{
int i;
// DeclineRate=(double)0.9;
// MarkovLengh=1000;
// MaxInnerLoop=200;
// MaxOuterLoop=10;
// CO=1;


DataMember=new DataType[DataNum];
ClusterMember=new ClusterType[K];

for(i=0;i{
DataMember[i].data=new double[Dimension];

DataMember[i].uncle=new double[K];
}
for(i=0;iClusterMember[i].center=new double[Dimension];

GetDataset(DataMember,DataSet,DataNum,Dimension);


}//endSAA


//****************初始化参数,及开始搜索状态

void SAA::Initialize( )
{

//K-均值聚类法建立退火聚类的

初始状态
// KMeans();


}

//*******************k-均值法进行聚类
//************接口:数据,数量,维数,类别
//逐点聚类方式

void SAA::KMeans()
{

int i,j,M=1;
int pa,pb,fa;
ClusterType *OldCluster;

//初始化聚类中心

OldCluster=new ClusterType[K];
for(i=0;i{
// cout<GetValue(ClusterMember[i].center,DataMember[i].data,Dimension);
ClusterMember[i].sonnum=1;

OldCluster[i].center=new double[Dimension];
GetValue(OldCluster[i].center,ClusterMember[i].center,Dimension);
}


for(i=0;i{
// cout<for(j=0;j{
DataMember[i].uncle[j]=SquareDistance(DataMember[i].data,ClusterMember[j].center,Dimension);
// cout<<" "<"<}
pa=DataMember[i].father=FindFather(DataMember[i].uncle,K);
if(i>=K)
{
// cout<ClusterMember[pa].sonnum+=1;
// cout<NewCenterPlus(ClusterMember,pa,DataMember[i].data,Dimension);
// cout<"<GetValue(OldCluster[pa].center,ClusterMember[pa].center,Dimension);
}
}

//开始聚类,直到聚类中心不再发生变化。××逐个修改法××
while(!HALT)
{
//一次聚类循环:1.重新归类;2.修改类中心
for(i=0;i{
// cout<for(j=0;j{
// cout<<" D "<DataMember[i].uncle[j]=SquareDistance(DataMember[i].data,ClusterMember[j].center,Dimension);
// cout<"<// cout<"<}

fa=DataMember[i].father;

if(fa!=FindFather(DataMember[i].uncle,K)&&ClusterMember[fa].sonnum>1)
{

pa=DataMember[i].father;
ClusterMember[pa].sonnum-=1;

pb=DataMember[i].father=FindFather(DataMember[i].uncle,K);
ClusterMember[pb].sonnum+=1;

NewCenterReduce(ClusterMember,pa,DataMember[i].data,Dimension);
NewCenterPlus(ClusterMember,pb,DataMember[i].data,Dimension);


/* cout<cout< "<
for(t=0;t{
cout<}

DisPlay();
M=M+1;
*/
}

}//endfor


//判断聚类是否完成,HALT=1,

停止聚类
HALT=0;
for(j=0;jif(Compare(OldCluster[j].center,ClusterMember[j].center,Dimension))
break;
if(j==K)
HALT=1;


for(j=0;jGetValue(OldCluster[j].center,ClusterMember[j].center,Dimension);

}//endwhile

}//end of KMeans

//批聚类方式

void SAA::KMeans1()
{
int i,j,M=1;
int pa,pb,fa;
ClusterType *OldCluster;

//初始化聚类中心

OldCluster=new ClusterType[K];
for(i=0;iOldCluster[i].center=new double[Dimension];

for(j=0;jGetValue(OldCluster[j].center,ClusterMember[j].center,Dimension);

//开始聚类,直到聚类中心不再发生变化。××逐个修改法××
while(!HALT)
{
//一次聚类循环:1.重新归类;2.修改类中心
for(i=0;i{
for(j=0;jDataMember[i].uncle[j]=SquareDistance(DataMember[i].data,ClusterMember[j].center,Dimension);
fa=DataMember[i].father;

if(fa!=FindFather(DataMember[i].uncle,K)&&ClusterMember[fa].sonnum>1)
{

pa=DataMember[i].father;
ClusterMember[pa].sonnum-=1;

pb=DataMember[i].father=FindFather(DataMember[i].uncle,K);
ClusterMember[pb].sonnum+=1;

NewCenterReduce(ClusterMember,pa,DataMember[i].data,Dimension);
NewCenterPlus(ClusterMember,pb,DataMember[i].data,Dimension);
}

}//endfor


//判断聚类是否完成,HALT=1,停止聚类
HALT=0;
for(j=0;jif(Compare(OldCluster[j].center,ClusterMember[j].center,Dimension))
break;
if(j==K)
HALT=1;


for(j=0;jGetValue(OldCluster[j].center,ClusterMember[j].center,Dimension);

}//endwhile

}

//几个经常需要调用的小函数

void SAA::NewCenterPlus(ClusterType *p1,int t,double *p2,int dim)
{
int i;
for(i=0;ip1[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;ip1[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{

for(j=0;jp1[i].data[j]=p2[i*dim+j];
}
}

void SAA::GetValue(double *str1,double *str2,int dim)
{
int i;
for(i=0;istr1[i]=str2[i];
}

int SAA::FindFather(double *p,int k)
{
int i,N=0;
double min=30000;

for(i=0;iif(p[i]{
min=p[i];
N=i;
}
return N;
}

double SAA::SquareDistance(double *str1,double *str2,int dim)
{
double dis=0;
int i;
for(i=0;idis=dis+(double)(str1[i]-str2[i])*(str1[i]-str2[i]);
return dis;
}

int SAA::Compare(double *p1,double *p2,int dim)
{
int i;
for(i=0;iif(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{
N=0;
cout<result<for(j=0;jif(DataMember[j].father==i)
{
cout<<" [";
for(t=0;tcout<<" "<cout<<" ] ";
if((N+1)%Row==0)
cout<
result<<" [";
for(t=0;tresult<<" "<result<<" ] ";
if((N+1)%Row==0)
result<
N=N+1;
}
}//end for

cout<result<
result.close();

}//end of Display

double SAA::AimFunction(DataType *q,ClusterType *c)
{
int i,j;
double *p;
p=new double[K];
for(i=0;ip[i]=0;
for(i=0;i{
for(j=0;jif(q[j].father==i)
{
p[i]=p[i]+SquareDistance(c[i].center,q[j].data,Dimension);
}
}


AimFunc=0;
for(i=0;iAimFunc=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<file<
file.close();
saa.DisPlay();

cout<
}



相关主题
相关文档
最新文档