首页 > 代码库 > 模式识别之聚类算法k-均值---k-均值聚类算法c实现
模式识别之聚类算法k-均值---k-均值聚类算法c实现
//写个简单的先练习一下,测试通过//k-均值聚类算法C语言版 #include <stdlib.h> #include <stdio.h> #include <time.h> #include <math.h>
#define TRUE 1 #define FALSE 0 int N;//数据个数 int K;//集合个数 int * CenterIndex;//初始化质心数组的索引 double * Center;//质心集合 double * CenterCopy;//质心集合副本 double * AllData;//数据集合 double ** Cluster;//簇的集合 int * Top;//集合中元素的个数,也会用作栈处理//随机生成k个数x(0<=x<=n-1)作为起始的质心集合void CreateRandomArray(int n, int k,int * center){ int i=0; int j=0; srand( (unsigned)time( NULL ) ); for( i=0;i<k;++i)//随机生成k个数 { int a=rand()%n; //判重 for(j=0;j<i;j++) { if(center[j]==a)//重复 { break; } } if(j>=i)//如果不重复,加入 { center[i]=a; } else { i--; //如果重复,本次重新随机生成 } } }//返回距离最小的质心的序号int GetIndex(double value,double * center){ int i=0; int index=i;//最小的质心序号 double min=fabs(value-center[i]);//距质心最小距离 for(i=0;i<K;i++) { if(fabs(value-center[i])<min)//如果比当前距离还小,更新最小的质心序号和距离值 { index=i; min=fabs(value-center[i]); } } return index;}//拷贝质心数组到副本void CopyCenter(){ int i=0; for(i=0;i<K;i++) { CenterCopy[i]=Center[i]; }}//初始化质心,随机生成法void InitCenter(){ int i=0; CreateRandomArray(N,K,CenterIndex);//产生随机的K个<N的不同的序列 for(i=0;i<K;i++) { Center[i]=AllData[CenterIndex[i]];//将对应数据赋值给质心数组 } CopyCenter();//拷贝到质心副本 }//加入一个数据到一个Cluster[index]集合void AddToCluster(int index,double value){ Cluster[index][Top[index]++]=value;//这里同进栈操作}//重新计算簇集合void UpdateCluster(){ int i=0; int tindex; //将所有的集合清空,即将TOP置0 for(i=0;i<K;i++) { Top[i]=0; } for(i=0;i<N;i++) { tindex=GetIndex(AllData[i],Center);//得到与当前数据最小的质心索引 AddToCluster(tindex,AllData[i]); //加入到相应的集合中 }}//重新计算质心集合,对每一簇集合中的元素加总求平均即可void UpdateCenter(){ int i=0; int j=0; double sum=0; for(i=0;i<K;i++) { sum=0; //计算簇i的元素和 for(j=0;j<Top[i];j++) { sum+=Cluster[i][j]; } if(Top[i]>0)//如果该簇元素不为空 { Center[i]=sum/Top[i];//求其平均值 } }}//判断2数组元素是否相等int IsEqual(double * center1 ,double * center2){ int i; for(i=0;i<K;i++) { if(fabs(center1[i]!=center2[i])) { return FALSE; } } return TRUE;}//打印聚合结果void Print(){ int i,j; printf("-------------------------------------- "); for(i=0;i<K;i++) { printf("第%d组: 质心(%f) ",i,Center[i]); for(j=0;j<Top[i];j++) { printf("%f ",Cluster[i][j]); } } }//初始化聚类的各种数据void InitData(){ int i=0; int a; printf("输入数据个数: "); scanf("%d",&N); printf("输入簇个数: "); scanf("%d",&K); if(K>N) { exit(0); } Center=(double *)malloc(sizeof(double)*K);//为质心集合申请空间 CenterIndex=(int *)malloc(sizeof(int)*K);//为质心集合索引申请空间 CenterCopy=(double *)malloc(sizeof(double)*K);//为质心集合副本申请空间 Top=(int *)malloc(sizeof(int)*K); AllData=http://www.mamicode.com/(double *)malloc(sizeof(double)*N);//为数据集合申请空间"输入%d数据:",N); for(i=0;i<N;i++) { scanf("%d",&(a)); AllData[i]=a; } InitCenter();//初始化质心集合 UpdateCluster();//初始化K个簇集合}/*算法描述:K均值算法: 给定类的个数K,将N个对象分到K个类中去, 使得类内对象之间的相似性最大,而类之间的相似性最小。*/main(){ int Flag=1;//迭代标志,若为false,则迭代结束 int i=0; InitData();//初始化数据 while(Flag)//开始迭代 { UpdateCluster();//更新各个聚类 UpdateCenter(); //更新质心数组 if(IsEqual(Center,CenterCopy))//如果本次迭代与前次的质心聚合相等,即已收敛,结束退出 { Flag=0; } else//否则将质心副本置为本次迭代得到的的质心集合 { CopyCenter();//将质心副本置为本次迭代得到的的质心集合 } } Print();//输出结果 getchar(); getchar();}
模式识别之聚类算法k-均值---k-均值聚类算法c实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。