C++实现k-means 算法, Machine Learning, Computer Vison
Hang_Kmeans.h 文件
#include "StdAfx.h"
#include "Hang_Kmeans.h"
Re_Kmeans::Re_Kmeans(void)
{
}
Re_Kmeans::~Re_Kmeans(void)
{
}
void Re_Kmeans::Inti_Cluser_Center(double*x_data,int x_num,int dim,int k_cluser,double*cer_point)
{
//根据,要划分的聚类的群数,选择原始数据的索引位置点随机选取簇类中心
set <int> A;
set<int>::iterator iter;
srand((int)time(0));
//选取初始聚类中心
for (int i=0;i<x_num;i++)
{
int cluer_num=rand()%(x_num);
if (A.size()<k_cluser)
{
A.insert(cluer_num);
}
}
vector<int> clu_number;
for( iter=A.begin();iter!=A.end();iter++)
{
clu_number.push_back(*iter);
}
for (int i=0;i<clu_number.size();i++)
{
cer_point[i*dim+0]=x_data[clu_number[i]*dim+0];
cer_point[i*dim+1]=x_data[clu_number[i]*dim+1];
}
A.clear();
clu_number.clear();
}
void Re_Kmeans::Cluser_dis(double*x_data,int x_num,int dim,double*Inti_cerpoint,int k_cluser, vector<min_pos>&cluse_num)
{
double*dis=new double[x_num*k_cluser];
min_pos pos;
for (int k=0;k<k_cluser;k++) //计算每个点到初始类中心的距离
{
for (int i=0;i<x_num;i++)
{
dis[i*k_cluser+k]=sqrt(pow((x_data[i*dim+0]-Inti_cerpoint[k*dim+0]),2)+pow((x_data[i*dim+1]-Inti_cerpoint[k*dim+1]),2));
}
}
for (int i=0;i<x_num;i++) //分类
{
double dis_Int=dis[i*k_cluser+0];
for (int k=0;k<k_cluser;k++)
{
if (dis[i*k_cluser+k]<=dis_Int)
{
dis_Int=dis[i*k_cluser+k];
pos.dis=dis[i*k_cluser+k];
pos.pointind=k;
}
}
cluse_num.push_back(pos);
}
delete[] dis;
}
void Re_Kmeans::Re_cerpoint(double*x_data,int x_num,int dim,vector<min_pos>&cluse_num,int k_cluse,double*cer_pot)
{
for (int k=0;k<k_cluse;k++)
{
int count=0;
cer_pot[k*dim+0]=0.0;
cer_pot[k*dim+1]=0.0;
for (int i=0;i<x_num;i++)
{
if (cluse_num[i].pointind==k)
{
cer_pot[k*dim+0]=cer_pot[k*dim+0]+x_data[i*dim+0];
cer_pot[k*dim+1]=cer_pot[k*dim+1]+x_data[i*dim+1];
count=count+1;
}
}
cer_pot[k*dim+0]= cer_pot[k*dim+0]/count;
cer_pot[k*dim+1]= cer_pot[k*dim+1]/count;
}
}
void Re_Kmeans:: Chenk_point(double*cer_point,int k_cluser,int dim)
{
Point pot;
vector<Point> cerpot;
double a=0.0;
int Re_kluser=0;
for (int i=0;i<k_cluser;i++)
{
if ((abs(cer_point[i*dim+0])<65535)&&(abs(cer_point[i*dim+1])<65535))
{
pot.x=cer_point[i*dim+0];
pot.y=cer_point[i*dim+1];
cerpot.push_back(pot);
Re_kluser=Re_kluser+1;
}
else
continue;
}
k_cluser=Re_kluser;
for (int i=0;i<Re_kluser;i++)
{
cer_point[i*dim+0]=cerpot[i].x;
cer_point[i*dim+1]=cerpot[i].y;
}
cerpot.clear();
}
void Re_Kmeans::Kmeans(double *x_data,int x_num,int dim,int k_cluser,double*cer_point)
{
vector<min_pos>cluse_num;
Inti_Cluser_Center(x_data,x_num,dim,k_cluser,cer_point);
for(int iter=0;iter<20;++iter)
{
Cluser_dis(x_data,x_num,dim,cer_point,k_cluser,cluse_num);
Re_cerpoint(x_data,x_num,dim,cluse_num,k_cluser,cer_point);
cluse_num.erase(cluse_num.begin(),cluse_num.end());
}
//Chenk_point(cer_point,re_kluser,dim);
}
参考: http://www.hangzh.com/