📄 c_mean.cpp
字号:
// c均值算法 潘水洋 //
#include <iostream.h>
#include <math.h>
#define N 2 //样本为2维矢量
#define M 20 //待分类的20个样本数
#define C 2
typedef struct { //定义结构体类型
double x[N];
} PATTERN;
PATTERN p[M]={ //待分类的20个样本
{0,0},{1,0},{0,1},{1,1},{2,1},{1,2},{2,2},{3,2},{6,6},{7,6},
{8,6},{6,7},{7,7},{8,7},{9,7},{7,8},{8,8},{9,8},{8,9},{9,9}
};
PATTERN z[C],oldz[C];
int nj[C];
int cindex[C][M]; //存放分类之后的样本
double Eucliden(PATTERN x,PATTERN y) //计算两个样本之间的欧式距离
{
int i;
double d;
d=0.0;
for (i=0;i<N;i++) {
d+=(x.x[i]-y.x[i])*(x.x[i]-y.x[i]);
}
d=sqrt(d);
return d;
}
bool zequal(PATTERN z1[],PATTERN z2[]) //判断分类后新的类中心与前一次分类类中心距离是否小于0.00001,若满足返回真值
{
int j;
double d;
d=0.0;
for (j=0;j<C;j++) {
d+=Eucliden(z1[j],z2[j]);
}
if (d<0.00001) return true;
else return false;
}
void main() //c均值核心算法
{
int i,j,l,f=0;
double d,dmin;
for (j=0;j<C;j++) { //初始分类,将p[0]作为w[1]类的初始类中心
z[j]=p[j]; //将p[1]作为w[1]类的初始类中心
}
do {
for (j=0;j<C;j++) {
nj[j]=0;
oldz[j]=z[j];
}
for (i=0;i<M;i++) {
for (j=0;j<C;j++) {
d=Eucliden(z[j],p[i]); //计算各个样本分别到两个类心的距离d
if (j==0) {dmin=d;l=0;}
else {
if (d<dmin) {
dmin=d;
l=j; //将距离d较小的样本,判给对应的类
}
}
}
cindex[l][nj[l]]=i; //cindex[0][nj[l]]存放属于w[1]类的样本
nj[l]++; //cindex[1][nj[l]]存放属于w[2]类的样本
}
f++;
int K ;
cout<<"第"<<f<<"次分类结果为: "<<endl; //输出每次分类结果
cout<<"w1类: "<<endl;
for (K=0;K<nj[0];K++)
{
cout<<"{"<<p[cindex[0][K]].x[0]<<","<<p[cindex[0][K]].x[1]<<"} ";
}
cout<<endl;
cout<<"w2类: "<<endl;
for (K=0;K<nj[1];K++)
{
cout<<"{"<<p[cindex[1][K]].x[0]<<","<<p[cindex[1][K]].x[1]<<"} ";
}
cout<<endl;
for (j=0;j<C;j++) { //计算分类后,新的类心
if (nj[j]==0) continue;
for (i=0;i<N;i++) {
d=0.0;
for (l=0;l<nj[j];l++) {
d+=p[cindex[j][l]].x[i];
}
d/=nj[j];
z[j].x[i]=d;
}
}
} while (!zequal(z,oldz)); //若函数zequal返回真值结束分类
i=9;
do
{i=9;}
while(i=9);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -