3.点的聚类:
例子如下:
使用你所学到的k均值聚类算法分别按照欧拉距离(平面直角坐标系里的两点间距离公式)和曼哈顿距离(两个点上在标准坐标系上的绝对轴距总和),将下面的点分成三类:
基于欧拉距离的程序代码(C语言)
#include<stdio.h>
#include<math.h>
#define N 15
#define k 3
int min(float d[k])
{
inti=0; /*定义最短距离下标*/
if(d[1]<d[i])
i=1;
if(d[2]<d[i])
i=2;
returni; /*返回最短距离下标*/
}
int main()
{
floata[N][2]={{0,0},{2,3},{4,2},{0,6},{14,3},
{13,5},{3,10},{4,11},{6,9},{8,10},{12,6},
{17,3},{14,6},{7,9},{9,12}}; /*N个点,坐标*/
inti,j,m;
inticounter[k],n=0; /*各簇元素个数,聚类次数*/
floatc[k][2]; /*聚类中心*/ float c1[k][2]; /*新聚类中心*/
floats[k][2]; /*各簇元素坐标和*/
floatd[k]; /*距离*/
intitype; /*元素所在的簇*/
floattype[k][N][2]; /*初始化,K簇,每簇含N个元素*/
for(j=0;j<k;j++)
{
c1[j][0]=a[j][0]; /*初始化聚类中心*/
c1[j][1]=a[j][1];
}
do
{
n++;
for(i=0;i<k;i++)
{
icounter[i]=0; /*每次聚类计数器归零*/
for(m=0;m<2;m++)
{
s[i][m]=0; /*各簇元素坐标和归零*/
c[i][m]=c1[i][m];
/*新聚类中心赋值给原聚类中心*/
}
}
for(i=0;i<N;i++) /*遍历数组*/
{
for(j=0;j<k;j++)
d[j]=fabs(a[i][0]-c[j][0])+fabs(a[i][1]-c[j][1]);
/*欧拉距离*/
itype=min(d); /*调用min函数*/
for(m=0;m<2;m++)
{
type[itype][icounter[itype]][m]=a[i][m];
s[itype][m]+=a[i][m];
}
icounter[itype]++;
}
for(i=0;i<k;i++)
{
c1[i][0]=s[i][0]/icounter[i]; /*新聚类中心*/
c1[i][1]=s[i][1]/icounter[i];
}
/*输出每次聚类得到的结果*/
printf("第%d次基于欧拉距离聚类结果:\n",n);
for(j=0;j<k;j++)
{
printf("聚类中心(%f,%f):\t",c[j][0],c[j][1]);
for(i=0;i<icounter[j];i++)
{
printf("(%.f,%.f)",type[j][i][0],type[j][i][1]);
}
printf("\n");
}
printf("\n");
}while((fabs(c1[0][0]-c[0][0])>1e-5) ||
(fabs(c1[1][0]-c[1][0])>1e-5) ||
(fabs(c1[2][0]-c[2][0])>1e-5));
/*聚类结果收敛时跳出循环*/
/*打印最终聚类结果*/
printf("\n基于欧拉距离%d次聚类后结果收敛,最终聚类结果:\n",n);
for(j=0;j<k;j++)
{
printf("聚类中心(%.2f,%.2f):\t",c1[j][0],c1[j][1]);
for(i=0;i<icounter[j];i++)
{
printf("(%.f,%.f)",type[j][i][0],type[j][i][1]);
}
printf("\n");
}
return0;
}
运行结果
基于欧拉距离
聚类中心
元素
( 1.5, 2.75)
(0,0) (2,3) (4,2) (0,6)
( 6.17, 10.17)
(3,10) (4,11) (6,9) (7,9) (9,12)
( 14, 4.6)
(14,3) (13,5) (12,6) (17,3) (14,6)
基于曼哈顿距离
聚类中心
元素
( 1.5, 2.75)
(0,0) (2,3) (4,2) (0,6)
( 6.17, 10.17)
(3,10) (4,11) (6,9) (7,9) (9,12)
( 14, 4.6)
(14,3) (13,5) (12,6) (17,3) (14,6) |