关于K均值算法的问题,有错误但不知如何改正,新手求解!
k均值算法.rar
(1.95 KB)
//k均值算法: //第一步:选K个初始聚类中心,z1(1),z2(1),…,zK(1),其中括号内的序号为寻找聚类中心的迭代运算的次序号。聚类中心的向量值可任意设定,例如可选开始的K个模式样本的向量值作为初始聚类中心。 //第二步:逐个将需分类的模式样本{x}按最小距离准则分配给K个聚类中心中的某一个zj(1)。 //假设i=j时,,则,其中k为迭代运算的次序号,第一次迭代k=1,Sj表示第j个聚类,其聚类中心为zj。 //第三步:计算各个聚类的新的中心zj(k+1),j=1,2,…,K //其中Nj为第j个聚类域Sj中所包含的样本个数。以均值向量作为新的聚类中心,可使如下聚类准则函数最小: //在这一步中要分别计算K个聚类中的样本均值向量,所以称之为K-均值算法。 //第四步:若,j=1,2,…,K,则返回第二步,将模式样本逐个重新分类,重复迭代运算; //若,j=1,2,…,K,则算法收敛,计算结束。 //define #define MAX 1000000 #define K 10 #define DIM 2 #include <stdio.h> #include <math.h> typedef struct{ float grid[2];//erwei shuzu chucun dian de zuo biao int label; //shi juleizhongxin zhi wei 1 }point; point sample[100]; //hanshu //聚类准则函数 //最小距离准则函数min() void min(float*a,float*b);//各点按最小距离分类 void find(point *p,int *center);//寻找新聚类中心函数 void classify(point *p,int *center);//归类 float distance(float*a,float*b); void main() {//将样本点坐标存入结构体 int i,j,k=0; float point[K*2]={0,0,3,8,2,2,1,1,5,3,4,8,6,3,5,4,6,4,7,5}; for(i=0;i<K;i++) for(j=0;j<DIM;j++) for(k=0;k<K;k++) { sample[i].grid[j]=point[k]; } int center[100]={0}; center[0]=0; center[1]=1; center[2]=2;//给定初始三类聚类中心 //jilu juleizhongxingeshu ,前面是聚类中心点xiabiao,后面新聚类中心 //将样本点坐标存入结构体 find(sample,center); classify(sample,center); printf("共有%d个聚类中心\n",center[K]); for(i=0;i<K;i++) if(sample[i].label==1) printf(" 点%d为聚类中心\n",i+1); for(i=0;i<K;i++) if(sample[i].label!=1) printf("点%d属于聚类中心%d\n",i+1,sample[i].label); //改!!!!!!!!!!!!!!!!! } float distance(float *a,float *b) { int i; float distance=0; for(i=0;i<DIM;i++) { distance+=(a[i]-b[i])*(a[i]-b[i]); } return distance; } void min(float*a,float*b)//最小距离准则分类 { int i,j,k; float dis=MAX; float dis1[1000000];//存储距离数组 float point[K*2]={0,0,3,8,2,2,1,1,5,3,4,8,6,3,5,4,6,4,7,5}; for(i=0;i<K;i++) for(j=0;j<DIM;j++) for(k=0;k<K;k++) { sample[i].grid[j]=point[k]; } int center[100]; int N[3]={0,0,0};//记录每一类中有几个点 for(i=0;i<K;i++) for(k=0;k<3;k++)//选了三个初始聚类中心,依次和每个聚类中心在每个聚类中心内距离找最小值 { dis1[k]=distance(sample[i].grid,sample[center[k]].grid); if(dis1[k]<dis) { dis=dis1[k]; sample[i].label=center[k]; N[k]++; } } } void find(point *p,int *center) //寻找新聚类中心函数:现在有三类,在每一类中寻找新的聚类中心,每一类中有N【k】个点,新的聚类中心点centre【K+1】向量坐标求和除上这类点的个数,再将十个样本点重新分类,迭代运算 { int k,i; //修改 int N[20]; // for(k=0;k<3;k++) for(i=0;i<K;i++) { if(sample[i].label==center[k]) //改(sample[center[K+1]].grid)+=(1\(N[k]))*sample[i].grid; sample[center[K+1]].grid+=(1/N[k])*sample[i].grid; //错误 //找到一个新的聚类中心center【K+1】 center[k+1]=K+1; } for(i=0;i<K;i++) for(k=0;k<K+1;k++) if(sample[center[K+1]].grid!=sample[center[k]].grid)//cuowu { min(sample[i].grid,sample[center[k]].grid); } } /* void find(point *p,int *center) //寻找新聚类中心函数:现在有三类,在每一类中寻找新的聚类中心,每一类中有N【k】个点,新的聚类中心点centre【K+1】向量坐标求和除上这类点的个数,再将十个样本点重新分类,迭代运算 { int k,i; for(k=0;k<3;k++) for(i=0;i<K;i++) { if(sample[i].label==center[k]) (sample[center[K+1]].grid)+=(1\(N[k]))*sample[i].grid; //这一行改为sample[center[K+1]].grid+=(1/N[k])*sample[i].grid;,另外数组N没定义 //错误 //找到一个新的聚类中心center【K+1】 center[k+1]=K+1; } */