聚类问题的次优解算法

#include<iostream>

#include<math.h>

#include<time.h>

#include<stdlib.h>

#include<vector>

 

const int Max=1000000; //点最多的数目

const double low_limit=0; //点的横纵坐标下限

const double high_limit=255;

using namespace std;

 

class Point //点类

{

private:

       doubleX; //横坐标

       doubleY; //纵坐标

public:

       Point(doublea,double b):X(a),Y(b)

       {

       }

       inlinedouble GetX() const

       {

              returnX;

       }

       inlinedouble GetY() const

       {

              returnY;

       }

};

 

class Distance //计算点之间距离类

{

public:

       doubleoperator()(const Point& one,const Point& other)

       {

              doublea=pow((one.GetX()-other.GetX()),2);

              doubleb=pow((one.GetY()-other.GetY()),2);

              returnsqrt(a+b);

       }

};

 

class Cluster

{

private:

       vector<Point>center;//中心点集

       vector<Point>*association; //中心点所关联聚合点集,i个位置上的点集关联与第i个中心点

       vector<Point>pointset;//初始化点集

       intk; //k个聚类

       intn;

       voidRemove(int index); //pointset删除第index个点

       doubleFromCenterSetTopoint(int index); //计算从初始化点到中心点集的距离和

       intMaxLen(); //从初始化点集中选择一个与中心点集距离最大的点得索引号

       voidSelectShortestDistance(int index); //从初始化点集中选择一个与中心点集距离最近的点,并把它加入关联点集

       voidset_center(); //设置中心点集

       voidset_associate(); //设置关联点集

public:

       voidInit_PS(); //初始化点集

       voidAdjust_Cluster();

       voidShow_Cluster(); //显示聚类

};

 

void Cluster::Init_PS()

{

       cout<<"请输入初始化点的数目:";

       cin>>n;

       if(!cin.good())

       {

              cout<<"输入不合法,程序终止!"<<endl;

              cin.clear();

              exit(0);

       }

       if(n>=Max)

       {

              cout<<"点的数目过大,程序终止!"<<endl;

              exit(0);

       }

       inti;

       doublex,y;

       for(i=1;i<=n;i++)

       {

              cout<<"请输入第"<<i<<"个点的横坐标:";

              cin>>x;

              cout<<"请输入第"<<i<<"个点的纵坐标:";

              cin>>y;

              if(!cin.good())

              {

                     cout<<"输入异常,程序终止!"<<endl;

                     cin.clear();

                     exit(0);

              }

              if(!(x<=high_limit&& x>=low_limit) || !(y<=high_limit && y>=low_limit))

              {

                     cout<<"点的横纵坐标应该在"<<low_limit<<""<<high_limit<<"之间"<<endl;

                     i--;

                     cout<<"请重输该点坐标!"<<endl;

                     continue;

              }

              this->pointset.push_back(Point(x,y));

       }

       cout<<"请输入要生成聚类个数(必须在1"<<n/2<<"之间):";

       intt;

       cin>>t;

       if(!cin.good())

       {

              cout<<"输入异常,程序终止!"<<endl;

              cin.clear();

              exit(0);

       }

       if(!(t<=n/2&& t>=1))

       {

              cout<<"输入不合法,程序终止!"<<endl;

              exit(0);

       }

       k=t;

       this->association=newvector<Point>[k];

}

 

void Cluster::Remove(int index)

{

       intj;

       vector<Point>::iteratorit;

       for(j=0,it=this->pointset.begin();it!=this->pointset.end();it++,j++)

       {

              if(j==index)break;

       }

       this->pointset.erase(it);

}

 

double Cluster::FromCenterSetTopoint(intindex)

{

       vector<Point>::iteratorit;

       if(this->center.empty())return 0;

       Distanced;

       doublelen=0;

       for(it=this->center.begin();it!=this->center.end();it++)

       {

              len+=d(*it,this->pointset[index]);

       }

       returnlen;

}

 

int Cluster::MaxLen()

{

       if(this->pointset.empty()|| this->center.empty()) return -1;

       intindex,pos;

       doublemaxLen=0;

       vector<Point>::const_iteratorit;

       for(index=0,it=this->pointset.begin();it!=this->pointset.end();index++,it++)

       {

              if(this->FromCenterSetTopoint(index)>maxLen)

              {

                     maxLen=this->FromCenterSetTopoint(index);

                     pos=index;

              }

       }

       returnpos;

}

 

void Cluster::set_center()

{

       inti;

       for(i=1;i<=k;i++)

       {

              if(this->center.empty())//中心点集为空

              {

                     srand((unsigned)time(0));//从初始化点集随机选择一个点

                     intt=rand()%k;

                     if(t>0)t--; //使得t能够等于0

                     this->center.push_back(this->pointset[t]);

                     this->Remove(t);//pointset中删除此点

              }

              else

              {

                     intindex=this->MaxLen(); //index指向pointset中与中心点集距离最大的点的位置

                     this->center.push_back(this->pointset[index]);//将此点加入当前中心点集

                     this->Remove(index);

              }

       }

}

 

void Cluster::SelectShortestDistance(intindex)

{

       doubleshortestDistance=Max;

       vector<Point>::iteratorit;

       vector<Point>::iteratorpos; //指向中心点集合中与index所指向的点集合中某个点

       Distanced;

       doublelen;

       for(it=this->center.begin();it!=this->center.end();it++)

       {

              len=d(*it,this->pointset[index]);

              if(len<shortestDistance)

              {

                     shortestDistance=len;

                     pos=it;

              }

       }

       inti=pos-this->center.begin(); //i表示中心点集第i个点与index所指向的点集合中点距离最小

       this->association[i].push_back(this->pointset[index]);//加入第i个关联点集

}

 

void Cluster::set_associate()

{

       vector<Point>::iteratorit;

       intindex;

       for(index=0,it=this->pointset.begin();it!=this->pointset.end();it++,index++)

       {

              this->SelectShortestDistance(index);

       }

}

 

void Cluster::Adjust_Cluster()

{

       this->set_center();

       this->set_associate();

}

 

void Cluster::Show_Cluster()

{

       vector<Point>::const_iteratorit;

       inti=0;

       Distanced;

       for(it=this->center.begin();it!=this->center.end();it++,i++)

       {

              cout<<""<<i<<"个聚类"<<endl;

              cout<<""<<i<<"个中心点是:";

              cout<<"("<<it->GetX()<<","<<it->GetY()<<")"<<endl;

              cout<<"它所关联的聚类是:"<<endl;

              vector<Point>::const_iteratorpos;

              for(pos=this->association[i].begin();pos!=this->association[i].end();pos++)

              {

                     intindex=pos-this->association[i].begin();

                     cout<<""<<index<<"个点是:"<<"("<<pos->GetX()<<","<<pos->GetY()<<")"<<endl;

                     cout<<"它与中心点的距离是:"<<d(*it,*pos)<<endl;

              }

       }

}

 

void main()

{

       Clustercc;

       cc.Init_PS();

       cc.Adjust_Cluster();

       cc.Show_Cluster();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值