k-均值算法及其实现

k-均值算法及其实现

1.1 算法描述

     K均值算法也称为C-均值算法,是根据函数准则进行分类的聚类算法,基于使聚类准则最小化。所使用的聚类准则

函数为模式集中每一个样本点到该类聚类中心的距离平方和。聚类中心的选择应使得距离平方和最小。

     假设共有N个模式样本,算法执行步骤如下:

      (1) 任选K个初始聚类中心Z1(1),Z2(1),...,Zk(1),K<N。括号中为第几次迭代。一般选择前K个样本作为初始聚类中心。

      (2) 使用欧几里得公式计算其余样本点到初始聚类中心的距离,基于欧几里得最小距离为其余样本分配聚类中

                心,并将迭代次数加1。

                

                其中X为模式集,Sj为第j个聚类集,小写k为迭代次数,大写K为聚类中心个数,Dj(k)为到聚类中心的距 

                离。

      (3) 计算各个聚类中心的新向量值作为新的聚类中心。

      (4) 如果,则继续步骤(2),否则,算法收敛,计算结束。

1.2 算法实现

      算法实现效果如下图1所示。


图1 50个点使用k-均值聚为两类的算法实现效果

1.3 代码如下:

本代码使用了OpenGL图形程序接口,需要使用glut库,具体使用方法请自行查找相关文档,此处不再介绍。
/*
k-均值算法,聚为两类
*/
#define N1  50
#define R 2.0f
#define Pi 3.1415926f
#include <stdio.h>
#include <vector>
#include <time.h>
#include <GL/glut.h>

//模式结构体
struct Pattern
{
	float x1,x2;//x1,x2表示特征
};
//定义初始聚类中心A,B以及初始数据w1
int p,q;
Pattern w1[N1],w2[N1],w3[N1];
void init()
{
	glClearColor(1.0f,1.0f,1.0f,1.0f);
	glClear(GL_COLOR_BUFFER_BIT);
}
void display()
{
	//画点
	glPointSize(10.0);
	glBegin(GL_POINTS);
	for(int i = 0;i < p; i++)
	{
		glColor3f(1.0,0.0,0.0);
		glVertex2f(w2[i].x1,w2[i].x2);
	}
	glEnd();
	glFlush();

	for (int i = 0; i < q; i++)
	{
		glBegin(GL_LINE_LOOP);
		for(int j = 0;j < q; j++)
		{
			glColor3f(0.0,0.0,1.0);
			glVertex2f(w3[i].x1+R*cos(2*Pi/q*j),w3[i].x2+R*sin(2*Pi/q*j));
		}
		glEnd();
		glFlush();
	}
}
int main(int argc,char *argv[])
{
	Pattern A,B,C,D,E,F;//定义初始聚类中心A,B
	Pattern distance[N1];
	//产生随机数的种子
	printf("这是K-均值算法的初始点数据\n");
	srand((unsigned)time(NULL));
	for (int i = 0; i < N1; i++)
	{
		w1[i].x1=rand()%100;
		w1[i].x2=rand()%100;
		//打印随机产生的点
		printf("%.3f %.3f\n",w1[i].x1,w1[i].x2);
	}
	//执行k-均值算法更新,赋值初始聚类中心
	A.x1=w1[0].x1;
	A.x2=w1[0].x2;
	B.x1=w1[1].x1;
	B.x2=w1[1].x2;
	int m,n;
	E.x1=A.x1;E.x2=A.x2;
	F.x1=B.x1;F.x2=B.x2;
	int temp =0;
	while(true)
	{
		temp++;
		m=0;
		n=0;
		p=0;
		q=0;
		C.x1=0;
		C.x2=0;
		D.x1=0;
		D.x2=0;
		for(int j = 0;j < N1;j++)
			//计算各样本距离聚类中心的距离
		{
			distance[j].x1=sqrt((w1[j].x1-E.x1)*(w1[j].x1-E.x1)+(w1[j].x2-E.x2)*(w1[j].x2-E.x2));
			distance[j].x2=sqrt((w1[j].x1-F.x1)*(w1[j].x1-F.x1)+(w1[j].x2-F.x2)*(w1[j].x2-F.x2));
			if(distance[j].x1<distance[j].x2)
			{
				m++;
				w2[p].x1=w1[j].x1;
				w2[p].x2=w1[j].x2;
				C.x1+=w2[p].x1;
				C.x2+=w2[p].x2;
				p++;	
				}
				else
				{
					n++;
					w3[q].x1=w1[j].x1;
					w3[q].x2=w1[j].x2;
					D.x1+=w3[q].x1;
					D.x2+=w3[q].x2;
					q++;
				}
		}
		C.x1=(float)C.x1/m;
		C.x2=(float)C.x2/m;
		D.x1=(float)D.x1/n;
		D.x2=(float)D.x2/n;
		if(E.x1 != C.x1 || E.x2 != C.x2 || F.x1 != D.x1 || F.x2 != D.x2)
		{
			E.x1=C.x1;E.x2=C.x2;
			F.x1=D.x1;F.x2=D.x2;
		}
		else
		{
			printf("第1类点的个数为:");
			printf("%d\n",m);
			printf("第2类点的个数为:");
			printf("%d\n",n);
			printf("最终的聚类中心为:\n");
			printf("%f,%f\n",C.x1,C.x2);
			printf("%f,%f\n",D.x1,D.x2);
			break;
		}
	}
	
	glutInit(&argc,argv);//初始化glut
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//设置显示属性为RGB颜色,单缓冲
	glutInitWindowSize(400,400);//设置窗口大小
	glutInitWindowPosition(200,100);//设置窗口位置
	glutCreateWindow("k-均值算法的设计");//生成窗口
	init();
	gluOrtho2D(-10,100,-10,100);
	glutDisplayFunc(display);//显示回调
	glutMainLoop();
	system("pause");
	return 0;
}




  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值