#include<iostream>此肢此
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std
int N //数据个数
int K //集合个数
int *CenterIndex//质心索引集合,即属于第几个参考点
double *Center //质心集合
double *CenterCopy
double *DataSet
double **Cluster
int *Top
/*算法描饥氏述:
C-Fuzzy均值聚类算法采用的是给定类的个数K,将N个元素(对象)分配到K个类中去使得类内对象之间的相似性最大,而类之间的相似性最小 */
//函数声明部分
void InitData()
void InitCenter()
void CreateRandomArray(int n,int k,int *centerIndex)
void CopyCenter()
void UpdateCluster()
void UpdateCenter()
int GetIndex(double value,double *centerIndex)
void AddtoCluster(int index,double value)
void print()
bool IsEqual(double *center,double *centercopy)
int main()
{
int Flag=1
InitData()
while(Flag)//无限次循环
{
UpdateCluster()
UpdateCenter()
if(IsEqual(Center,CenterCopy))
{
Flag=0
}
else
{
CopyCenter()
}
}
print()
getchar()
system("pause")
}
void InitData()
{
int i=0
int a
cout<<"请输入数据元素的个数: "
cin>>N
cout<<"请输入分类数: "
cin>>K
if(K>N)
{
return
}
CenterIndex =new int [sizeof(int)]
Center =new double [sizeof(double)*K]
CenterCopy =new double [sizeof(double)*K]
DataSet =new double [sizeof(double)*N]
Cluster =new double* [sizeof(double*)*K]
Top =new int [sizeof(int)*K]
//初始化K个类的集合
for(i=0i<Ki++)
{
Cluster[i]=new double [sizeof(double)*N]
Top[i]=0
}
cout<<"请输入数据"<<endl
for(i=0i<Ni++)
{
cin>>a
DataSet[i]=a
}
//初始化质心集合
InitCenter()
UpdateCluster()
}
void InitCenter()//初始化中心点(参照点)
{
int i=0
//产生随即的K个<N的不同的序列
CreateRandomArray(N,K,CenterIndex)
for(i=0i<Ki++)
{
Center[i]=DataSet[CenterIndex[i]]
}
CopyCenter()
}
void CreateRandomArray(int n,int k,int *centerIndex)//产生可以随输出控制的 k与n (可舍弃)
{
int i=0,j=0
for(i=0i<Ki++)
{
int a=rand()%n
for(j=0j<ij++)
{
if(centerIndex[j]==a)
break
}
if(j>=i)
{
centerIndex[i]=a
}
else
{
i--
}
}
}
void CopyCenter()//将旧的中心点保留以作森迅比较
{
int i=0
for(i=0i<Ki++)
{
CenterCopy[i]=Center[i]
}
}
void UpdateCluster()//
{
int i=0
int tindex
for(i<Ki++)
{
Top[i]=0
}
for(i=0i<Ni++)
{
tindex=GetIndex(DataSet[i],Center)
AddtoCluster(tindex,DataSet[i])
}
}
int GetIndex(double value,double *center)//判断属于哪个参照点
{
int i=0
int index=i
double min=fabs(value-center[i])
for(i=0i<Ki++)
{
if(fabs(value-center[i])<min)
{
index=i
min=fabs(value-center[i])
}
}
return index
}
void AddtoCluster(int index,double value)//统计每组个数(用于均值法求新的参照点)
{
Cluster[index][Top[index]]=value
Top[index]++
}
void UpdateCenter()//更新参照点
{
int i=0,j=0
double sum
for(i=0i<Ki++)
{
sum=0.0
for(j=0j<Top[i]j++)
{
sum+=Cluster[i][j]
}
if(Top[i]>0)
{
Center[i]=sum/Top[i]
}
}
}
bool IsEqual(double *center,double*centercopy)//
{
int i
for(i=0i<Ki++)
{
if(fabs(center[i]!=centercopy[i]))
return 0
}
return 1
}
void print()//
{
int i,j
cout<<"===================================="<<endl
for(i=0i<Ki++)
{
cout<<"第"<<i<<"组:质心为:"<<Center[i]<<endl
cout<<"数据元素为:\n"
for(j=0j<Top[i]j++)
{
cout<<Cluster[i][j]<<'\t'
}
cout<<endl
}
}
在聚类分析中,K-均值聚类算法(雹胡k-means algorithm)是无监督分类中的一种基本方法,其也称为C-均值算法,其基本思想是:通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果.\x0d假设要把样本集分为c个类别,算法如下:\x0d(1)适当选择c个类的初始中心;\x0d(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的瞎肆枣中心所在的类,\x0d(3)利用均值等方法更新该类的中心值;\x0d(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代.\x0d下面介绍作者编写的一个分两类的程序,可以把其作为函数调用.\x0d%% function [samp1,samp2]=kmeans(samp)作为调用函数时去掉注释符\x0dsamp=[11.1506 6.7222 2.3139 5.9018 11.0827 5.7459 13.2174 13.8243 4.8005 0.9370 12.3576]%样本集\x0d[l0 l]=size(samp)\x0d%%利用均值把样本分为两类,再将每类的均值作为聚类中心\x0dth0=mean(samp)n1=0n2=0c1=0.0c1=double(c1)c2=c1for i=1:lif samp(i)<th0\x0dc1=c1+samp(i)n1=n1+1elsec2=c2+samp(i)n2=n2+1endendc1=c1/n1c2=c2/n2%初始聚类中心t=0cl1=c1cl2=c2\x0dc11=c1c22=c2%聚类中磨拆心while t==0samp1=zeros(1,l)\x0dsamp2=samp1n1=1n2=1for i=1:lif abs(samp(i)-c11)<abs(samp(i)-c22)\x0dsamp1(n1)=samp(i)\x0dcl1=cl1+samp(i)n1=n1+1\x0dc11=cl1/n1elsesamp2(n2)=samp(i)\x0dcl2=cl2+samp(i)n2=n2+1\x0dc22=cl2/n2endendif c11==c1 &&c22==c2t=1endcl1=c11cl2=c22\x0dc1=c11c2=c22\x0dend %samp1,samp2为聚类的结果.\x0d初始中心值这里采用均值的办法,也可以根据问题的性质,用经验的方法来确定,或者将样本集随机分成c类,计算每类的均值.\x0dk-均值算法需要事先知道分类的数量,这是其不足之处.欢迎分享,转载请注明来源:内存溢出
评论列表(0条)