该聚类算法不描述,下面的算法是针对对象只有单一属性的集合。
运行速度有些慢。可以将准则函数的收敛判断替换成进行迭代的次数
#include"stdio.h"
#include"iostream"
#include"time.h"
#include"math.h"
using namespace std;
#define max 1000
typedef struct ts_uc_arr
{
float d;//存储初始数据
int ic;//所属的聚类
} ts_uc_arr;
void main()
{
//cout<<"Hello"<<endl;
float tsum = 0;
int tcount = 0;
int j;
float e = 0;//准则函数
float et = -2;//存储准则函数上次的计算值
int n;
int k;//要分的簇数
int tmpk=-1;//暂存该对象是属于哪个簇的
float dis=3.4e38;//对象计算的距离
float *f_cen_arr;
cout<<"Input n Objects:"<<endl;
cin>>n;
ts_uc_arr * tst_uc_arr = new ts_uc_arr[n];
srand((unsigned)time(NULL));
for(int i = 0;i < n;i++)//生成初始的待分类数据
{
tst_uc_arr[i].d = (float)(rand()/max);
tst_uc_arr[i].ic = -1;
//cout<<tst_uc_arr[i].d<<":"<<tst_uc_arr[i].ic<<endl;
}
cout<<"Input how many clusters to calculate:"<<endl;
cin>>k;
f_cen_arr = new float[k];
for(i = 0;i < k;i++)//初始化中心
{ f_cen_arr[i] = tst_uc_arr[i].d;
tst_uc_arr[i].ic = i;
//cout<<f_cen_arr[i]<<":"<<tst_uc_arr[i].d<<endl;
}
while(e - et > 1)//判别准则函数是否收敛
{
for(i = 0;i < n;i++)
{
for( j = 0;j < k;j++)
{
if(sqrt((tst_uc_arr[i].d-f_cen_arr[j])*(tst_uc_arr[i].d-f_cen_arr[j])) < dis)
{
dis = sqrt((tst_uc_arr[i].d-f_cen_arr[j])*(tst_uc_arr[i].d-f_cen_arr[j]));
tmpk = j;
}
}
tst_uc_arr[i].ic = tmpk;//一次计算后该对象应该所属的簇
dis=3.4e38;//每次距离要重新初始化
}
for(j = 0;j < k;j++)//计算簇的新的中心
{
for(i = 0;i < n;i++)
{
if(tst_uc_arr[i].ic == j){tsum += tst_uc_arr[i].d;++tcount;}
}
f_cen_arr[j] = (tsum / tcount);
tsum = 0;
tcount = 0;
}
et = e;
for(j = 0;j < k;j++)//计算准则函数
{
for(i = 0;i < n;i++)
{
if(tst_uc_arr[i].ic == j){tsum += (tst_uc_arr[i].d-f_cen_arr[j])*(tst_uc_arr[i].d-f_cen_arr[j]);}
}
e += tsum;
tsum = 0;
}
}
for( i = 0;i < n;i++)//输出聚类后的结果
{
//tst_uc_arr[i].d = (float)(rand()/max);
//tst_uc_arr[i].ic = -1;
cout<<tst_uc_arr[i].d<<":"<<tst_uc_arr[i].ic<<endl;
// cout<<f_cen_arr[i]<<endl;
}
}