自己写的Kmeans

#include <iostream>
#include <vector>
#include<algorithm>
#include<stdlib.h>
#include "fstream"
using namespace std;
typedef struct Point
{
	double x;
	double y;
	int label;
}Point;

class Sample
{
   public:
	   Sample(const string& file_name )
	   {
		   ifstream ifstr_man(file_name);
		   double d;
		   while (ifstr_man >> d)
			  { 
				  m_xsample.push_back(d);//将数据压入堆栈。//
				  ifstr_man>>d;
				  m_ysample.push_back(d);
				  int a;
				  ifstr_man>>a;
				  m_label.push_back(a);
		       }
		  ifstr_man.close();
	   }
	   Point Get_Sample(int i)
	   {
		   Point tempPoint ;
		   tempPoint.x=m_xsample[i];
		   tempPoint.y=m_ysample[i];
		   tempPoint.label =m_label[i];
		   return tempPoint;
	   }
	   int GetLabel(int i)
	   {
		   return m_label[i];
	   }
	   int GetNumberOfSample()
	   {return m_label.size();}
   private:
	   vector<double> m_xsample;
	   vector<double> m_ysample;
	   vector<int>m_label;
};

class Kmeans
{
private:
	int m_k;//聚类数目//
	vector<Point> m_center;
	Sample* m_sample;
public:
	Kmeans(int k,Sample*p_spamle )
	{ 
		m_k=k;
		m_sample =p_spamle;
	}
public:
	void InitCenter()
	{
		  int j=1 ;
		  m_center.push_back(  m_sample->Get_Sample(0));
		  int n=m_sample->GetNumberOfSample();

	      for (int i=1;i<m_k;i++)
	      {
			  int flag =0;
			  while(flag)
			  {  
				  j=(rand() % (n-1+1))+ 1;
				  Point x =m_sample->Get_Sample(j);
				  int m=0;
				  for (;m<i;m++)
				  {
					if (x.x-m_center[m].x<=0.00001||x.y-m_center[m].y<=0.00001)
					{
                        flag=1;
						break;
					}
				  }
				  if (m==i)
				  {
					  flag=0;
				  }
			  }
			   m_center.push_back(m_sample->Get_Sample(j)) ;	   
	      }
	}
	void setK(int n)
	{
		m_k=n;
	}
	double GetDistance(const Point& t1,const Point& t2)
	{
		return sqrt((t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y));
	}
	int FindTheSmallest(double a[],int n)
	{
		int position=0;
		double min=a[0];
		for (int i=0;i<n;i++)
		{
			if (a[i]<min)
			{
				min=a[i];
				position=i;
			}
		}
		return position;
	}
	void runClustering()
	{
		   int n=m_sample->GetNumberOfSample();
	      double *sumx =new double[m_k];
		  double *sumy =new double[m_k];
		  double *distance =new double[m_k];
		  int *number=new int[m_k];
		  vector<vector<int>> index(m_k);
		  for (int i=0;i<m_k;i++)
		  {
			  sumx[i]=0.0;
			  sumy[i]=0.0;
			  distance[i]=0.0;
			  number[i]=0;
		  }
		  int times=1;
		  int flag=1;
    while(flag)
		{
			       // 1.重新划分n样本属于哪个类中心
				   // 2.计算新的类中心
				  //  3判断变化
			 for (int i=0;i<m_k;i++)
		     {
			    sumx[i]=0.0;
			    sumy[i]=0.0;
			    distance[i]=0.0;
		     }
			        vector<Point> newcenter(m_k);
					for (int i=0;i<n;i++)
				   {
					    Point t=m_sample->Get_Sample(i);
					    for (int j=0;j<m_k;j++)
					    {
						     distance[j]=GetDistance(t,m_center[j]);
					    }
					    int position =FindTheSmallest(distance,m_k);
					    index[position].push_back(i);
				   }

					for (int i=0;i<m_k;i++)
					{
					       vector<int>::iterator a=index[i].begin();
						   while (a!=index[i].end())
						   {
							   Point t=m_sample->Get_Sample(*a);
							   sumx[i]+=t.x;
							   sumy[i]+=t.y;
							   a++;
						   }
						   double x =1.0*sumx[i]/index[i].size();
						   double y =1.0*sumy[i]/index[i].size();
						   newcenter[i].x=x; newcenter[i].y=y;
					}

					int k=0;
					for (int i=0;i<m_k;i++)
					{
						if ((newcenter[i].x-m_center[i].x<0.001)&&(newcenter[i].y-m_center[i].y<0.001))
						{
							k++;
						}
						m_center[i]=newcenter[i];
					}
					if (k==m_k)
					{
						flag=0;
					}
					if (times>=1000)
					{
						flag=0;
					}
					times++;
	}
		delete []sumx;
		delete []sumy;
		delete []distance;
	}
    void GetCenter()
	{
		for (int i=0;i<m_k;i++)
		{
			std::cout<<"("<<m_center[i].x<<", "<<m_center[i].y<<")"<<std::endl;
		}
		
	}
};

int main()
{
	Sample *sample =new Sample("sample.txt");
	Kmeans mykmeans(2,sample);
	mykmeans.InitCenter();
	mykmeans.runClustering();
	mykmeans.GetCenter();
	return 0;
}
</pre><pre name="code" class="cpp">
</pre><pre name="code" class="cpp">一下午写了一个Kmeans 有点乱随后整理

猜你喜欢

转载自blog.csdn.net/libin88211/article/details/24423627