//写个简单的先练习一下,测试通过
//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. 向php数组添加元素的方法哪种更高效

    $arr = array(); // 第一种 array_push($arr, 'test'); // 第二种 $arr[] = 'test'; 参考PHP官方文档:http://php.net/ma ...

  2. 【LeetCode】Maximum Depth of Binary Tree(二叉树的最大深度)

    这道题是LeetCode里的第104道题. 给出题目: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定 ...

  3. 图论trainning-part-1 F. Highways

    F. Highways Time Limit: 1000ms Memory Limit: 10000KB 64-bit integer IO format: %lld      Java class ...

  4. POJ 2092 Grandpa is Famous

    Grandpa is Famous Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 7153   Accepted: 3624 ...

  5. 用docker弹性部署自己的服务

    很久不看docker的东西了,之前了解的一些基本命令都忘得差不多了,适逢工作需要,再来复习巩固下.今天想完成的是:借助docker不部署下自己的服务. 环境准备 都说“巧妇难为无米之炊”,所以还是需要 ...

  6. POJ 1741 Tree ——点分治

    [题目分析] 这貌似是做过第三道以Tree命名的题目了. 听说树分治的代码都很长,一直吓得不敢写,有生之年终于切掉这题. 点分治模板题目.自己YY了好久才写出来. 然后1A了,开心o(* ̄▽ ̄*)ブ ...

  7. Unix(AIX,Linux)

    AIX全名为(Advanced Interactive Executive),它是IBM公司的UNIX操作系统. 虽然Linux和aix都是Unix兼容的操作系统,但他们在不同的领域存在各自的特点和差 ...

  8. 常州模拟赛d3t2 灰狼呼唤着同胞

    题目背景 我的母亲柯蒂丽亚,是一个舞者.身披罗纱,一身异国装扮的她,来自灰狼的村子. 曾经在灰狼村子担任女侍的她,被认定在某晚犯下可怕的罪行之后,被赶出了村子. 一切的元凶,都要回到母亲犯下重罪的那一 ...

  9. 【组合数+Lucas定理模板】HDU 3037 Saving

    acm.hdu.edu.cn/showproblem.php?pid=3037 [题意] m个松果,n棵树 求把最多m个松果分配到最多n棵树的方案数 方案数有可能很大,模素数p 1 <= n, ...

  10. VMware---之网卡设置

    闲来无事,扯点皮,详细说下NAT配置过程 NAT全称Network Address Translation网络地址转换,顾名思义,配置的重点也是地址转换. 步骤1.配置局域网段及网关 打开vmware ...