//写个简单的先练习一下,测试通过
//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=(double *)malloc(sizeof(double)*N);//为数据集合申请空间
     Cluster=(double **)malloc(sizeof(double *)*K);//为簇集合申请空间
     //初始化K个簇集合
     for(i=0;i<K;i++)
     {
         Cluster[i]=(double *)malloc(sizeof(double)*N);
         Top[i]=0;
     }
     printf("输入%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实现的更多相关文章

  1. Python聚类算法之基本K均值实例详解

    Python聚类算法之基本K均值实例详解 本文实例讲述了Python聚类算法之基本K均值运算技巧.分享给大家供大家参考,具体如下: 基本K均值 :选择 K 个初始质心,其中 K 是用户指定的参数,即所 ...

  2. 数学建模及机器学习算法(一):聚类-kmeans(Python及MATLAB实现,包括k值选取与聚类效果评估)

    一.聚类的概念 聚类分析是在数据中发现数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好.我们事先并不知道数据的正确结果(类标),通过聚类算法来发现和挖掘数据本身的结 ...

  3. 机器学习--K近邻 (KNN)算法的原理及优缺点

    一.KNN算法原理 K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法. 它的基本思想是: 在训练集中数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对 ...

  4. 算法导论----贪心算法,删除k个数,使剩下的数字最小

    先贴问题: 1个n位正整数a,删去其中的k位,得到一个新的正整数b,设计一个贪心算法,对给定的a和k得到最小的b: 一.我的想法:先看例子:a=5476579228:去掉4位,则位数n=10,k=4, ...

  5. 蓝桥杯 算法训练 区间k大数查询(水题)

    算法训练 区间k大数查询 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...

  6. 算法训练 区间k大数查询

    http://lx.lanqiao.org/problem.page?gpid=T11 算法训练 区间k大数查询   时间限制:1.0s   内存限制:256.0MB        问题描述 给定一个 ...

  7. 蓝桥杯--算法训练 区间k大数查询

                                                                                 算法训练 区间k大数查询   时间限制:1.0 ...

  8. 算法训练 区间K大数

    算法训练 区间k大数查询 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...

  9. N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.

    N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列.设计加密解密算法,且要求K<=15*N. ...

随机推荐

  1. 【转载】linux之sed用法

    linux之sed用法 原文地址:http://www.cnblogs.com/dong008259/archive/2011/12/07/2279897.html   sed是一个很好的文件处理工具 ...

  2. zoj 2176 Speed Limit

    Speed Limit Time Limit: 2 Seconds      Memory Limit: 65536 KB Bill and Ted are taking a road trip. B ...

  3. .NET重构(九):机房重构验收总结

    导读:机房收费系统个人重构版,在寒假前,已经结束了.嗯,这一路的过程,也挺心酸的.结合师傅验收时的指导.建议,对这一段时间的学习,进行一个总结. 一.学习过程 这一阶段的学习,按照师傅给的建议是:由浅 ...

  4. 使用Apriori算法进行关联分析

    关联分析是一种在大规模数据集中寻找有趣关系的任务.这些关系可以有两种形式:频繁项集或者关联规则.频繁项集是指经常出现在一块的物品的集合,关联规则暗示两种物品之间可能存在很强的关系.一个项集的支持度被定 ...

  5. Tomcat 调优技巧

    Tomcat 调优技巧:1.Tomcat自身调优: ①采用动静分离节约Tomcat的性能: ②调整Tomcat的线程池: ③调整Tomcat的连接器: ④修改Tomcat的运行模式: ⑤禁用AJP连接 ...

  6. Windows下ElasticSearch的使用方式 CURL+Cygwin+Head插件

    Windows使用ElasticSearch的命令方法 一.CURL(不推荐) 下载curl安装包,解压到指定目录,在命令行运行解压后的exe文件. 二.Cygwin(推荐) 安装Windows下类l ...

  7. hdu 1717

    小数化分数2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  8. 扰动函数和拉链法模拟HashMap的存储结构

    HashMap是Map接口下面的子孙,它对外是K,V结构存储的,而内部也着自己的存储结构,它的get操作是O(1)的时间复杂度,可以说是非常快的找到目录,而添加时,也是O(1),所以在键值存储里,它成 ...

  9. [BOI2007] Mokia

    题目描述 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它能够回 ...

  10. Log4J使用详情

    一 .Log4J使用详情 Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以 ...