最近学校新开的一门课——《模式识别》。
课本对算法介绍的截图:
1、看完课本提出的几个问题并做解答:
(1)θ是干嘛用的?
θ * D12来确定每个类的范围,也就是做为循环的一个结束条件。
(2)聚类中心有什么筛选条件?
这个算法里的聚类中心就是相距最远的那几个点。
(3)怎么去确定有几类?
相当于分裂,只要比定的阈值大,那么这一圈就可以分裂。
2、代码:
#include <iostream>
#include <math.h>
using namespace std;
const int N=10;//给定N个样本
int maxmindistance(float sample[][N],float theta)
{
int center[20];//保存聚类中心
float D[20][N];//保存D点与点之间的距离
float min[N];
int minindex[N];
int clas[N];
float theshold;
float D12=0.0;//第一个聚类和第二个聚类中的距离
float tmp=0;
int index=0;
center[0]=0;//first center第一个聚类选出来了
int i,k=0,j,l;
for(j=0;j<N;j++)
{
tmp=(sample[0][j]-sample[0][0])*(sample[0][j]-sample[0][0])+(sample[1][j]-sample[1][0])*(sample[1][j]-sample[1][0]);
D[0][j]=(float)sqrt(tmp);
if(D[0][j]>D12)
{
D12=D[0][j];
index=j;
}
}
center[1]=index;//second center第二个聚类选出来了
k=1;
index=0;
theshold=D12;
while(theshold>theta*D12)
{
for(j=0;j<N;j++)
{
tmp=(sample[0][j]-sample[0][center[k]])*(sample[0][j]-sample[0][center[k]])+
(sample[1][j]-sample[1][center[k]])*(sample[1][j]-sample[1][center[k]]);
D[k][j]=(float)sqrt(tmp);
}
for(j=0;j<N;j++)
{
float tmp=D12; //8.944
for(l=0;l<=k;l++)
if (D[l][j]<tmp)
{
tmp=D[l][j];
index=l;
}
min[j]=tmp; //横向比较选出最小的保存
minindex[j]=index; //并存入它们的下标
}//min-operate
float max=0;index=0;
for(j=0;j<N;j++)
if(min[j]>max)
{
max=min[j]; //找到最大的
index=j; //并找到相应的点的下标
}
if (max>theta*D12)
{
k++;
center[k]=index;
}// add a center
theshold=max;// prepare to loop next time
} //求出所有中心,final array min[] is still useful
for(j=0;j<N;j++)
clas[j]=minindex[j];
for(i=0;i<2;i++) //输出原来的坐标
{
for(j=0;j<N;j++)
cout<<sample[i][j]<<" ";
cout<<"\n";
}
cout<<"k="<<k+1<<" ";
cout<<"center(sample):";
for(l=0;l<k;l++)
cout<<center[l]+1<<"--";
cout<<center[k]+1;
cout<<"\n";
for(j=0;j<N;j++)
cout<<clas[j]+1<<" ";
cout<<"\n";
return k;
}
#include"maxmindistance.h"
int main()
{
float s[2][N]={{0,3,2,1,5,4,6,5,6,7},
{0,8,2,1,3,8,3,4,4,5}};
float theta;
cin>>theta;
maxmindistance(s,theta);
}