模式识别之聚类算法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=(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实现的更多相关文章
- Python聚类算法之基本K均值实例详解
Python聚类算法之基本K均值实例详解 本文实例讲述了Python聚类算法之基本K均值运算技巧.分享给大家供大家参考,具体如下: 基本K均值 :选择 K 个初始质心,其中 K 是用户指定的参数,即所 ...
- 数学建模及机器学习算法(一):聚类-kmeans(Python及MATLAB实现,包括k值选取与聚类效果评估)
一.聚类的概念 聚类分析是在数据中发现数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好.我们事先并不知道数据的正确结果(类标),通过聚类算法来发现和挖掘数据本身的结 ...
- 机器学习--K近邻 (KNN)算法的原理及优缺点
一.KNN算法原理 K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法. 它的基本思想是: 在训练集中数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对 ...
- 算法导论----贪心算法,删除k个数,使剩下的数字最小
先贴问题: 1个n位正整数a,删去其中的k位,得到一个新的正整数b,设计一个贪心算法,对给定的a和k得到最小的b: 一.我的想法:先看例子:a=5476579228:去掉4位,则位数n=10,k=4, ...
- 蓝桥杯 算法训练 区间k大数查询(水题)
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- 算法训练 区间k大数查询
http://lx.lanqiao.org/problem.page?gpid=T11 算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个 ...
- 蓝桥杯--算法训练 区间k大数查询
算法训练 区间k大数查询 时间限制:1.0 ...
- 算法训练 区间K大数
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.
N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列.设计加密解密算法,且要求K<=15*N. ...
随机推荐
- Mac设置命令别名
文件中添加 /Users/xxx/.bash_profile 添加别名命令: alias pull='git pull origin' 注意:等号后面不能有空格 从新读取配置文件: source ~/ ...
- EIGRP
因为rip的收敛时间长 尤其是使用过程中 链路down掉 重收敛的时间比较长 所以在中到大型的园区网中很少用到rip协议 只有在很小的局域网中用到rip 因为收敛时间可能会稍微短一些 ...
- 【JavaScript 12—应用总结】:弹出登录框
导读:上篇博客中,做好了个人中心的下拉菜单,这次,将做每个网站都会有的一个登录功能,以此类推,可以做出别的想要的弹出框,如错误提示啦,或者注册. 一.实现分析 首先:和下拉菜单一样,需要通过CSS样式 ...
- 刷题总结——疫情控制(NOIP2012提高组)
题目: 题目背景 NOIP2012 提高组 DAY2 试题. 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都 ...
- __getattr__ 与 __getattribute__的区别
原文博客地址 http://www.cnblogs.com/bettermanlu/archive/2011/06/22/2087642.html
- Java 学习(3):java 对象和类
目录: --- 对象 --- 类 --- 源文件的声明规则 --- Java 包 对象: 对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种: ...
- 军训分批(codevs 2751)
题目描述 Description 某学校即将开展军训.共有N个班级. 前M个优秀班级为了保持学习优势,必须和3位任课老师带的班级同一批. 问共有几批? 输入描述 Input Description N ...
- 洛谷P3393 逃离僵尸岛
题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入 ...
- linux-起步
学习网站: linux中国开源社区 Vmware下载与安装 https://blog.csdn.net/Ywaken/article/details/78839005 https://blog.csd ...
- js采用concat和sort将N个数组拼接起来的方法
<script type="text/javascript" > function concatAndSortArray(array1, array2) { if (a ...