⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmeans.cpp

📁 聚类研究
💻 CPP
字号:
// kmeans.cpp: implementation of the Ckmeans class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "cluster.h"
#include "kmeans.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define LITTLE_CIRCLE 50
#define LARGE_CIRCLE 100
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Ckmeans::Ckmeans()
{
	E1 = E2 =0.0;
    Cw = NULL;
	p = NULL;
	den = NULL;
	Cl_k = 0;
}
void Ckmeans::KMeans(const int count ,const int k )
{
//	initiate();
	double sum_x ,sum_y ;
	sum_x = sum_y = 0.0;
	do{
		int i,j,n;
		for( i = 0; i < count; i++)
		{
			int m = select(i,count,k);
			Cw[m].num[Cw[m].count++] = i;
		}
		for(  n = 0; n < k; n++)
		{
			for( j = 0; j < Cw[n].count ; j++)
			{
				sum_x += p[ Cw[n].num[j] ].x;
				sum_y += p[ Cw[n].num[j] ].y;
			}
			Cw[n].w.x = (int)(sum_x/Cw[n].count);
			Cw[n].w.y = (int)(sum_y/Cw[n].count);
			sum_x = 0.0;
			sum_y = 0.0;
		}
		for(i = 0; i< k;i++)
			for(j = 0; j<Cw[i].count ;j++)
				E1 += distance( Cw[i].w,p[ Cw[i].num[j] ] );
		if( (0 <= E1 - E2 && E1 - E2 < CONST_CHANGE) || ( E2 -E1 >= 0 && E2 - E1 < CONST_CHANGE) )
			break;
		E2 = E1;
		E1 = 0.0;
		for(  n = 0; n < k; n++)
		{
			Cw[n].count = 0;
		}
	}while(true);
//	show();

}

long Ckmeans::distance(point p1,point p2)
{
	long dis = 
		(p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y);
	return dis;
}

int Ckmeans::select(int n,int count,int k)
{
	if(n > count) 
	{
		AfxMessageBox("n > count");
		exit(0);
	}
	long *dis = new long[k];
	int result; 
	bool find = false;
	for(int i = 0; i<k ;i++)
		dis[i] = distance(Cw[i].w,p[n]);
	for(int m = 0;m < k;m++)
	{
		for(int j= 0; j<k; j++)
			if(dis[m] > dis[j])
			{
				find = true;
			    break;
			}
    	if( find == false )
		{
		result = m ;
		break;
		}
		find = false;
	}
	return result;
}
void Ckmeans::dense(int count)
{
	den = new int[count];
	for(int k = 0;k < count; k++)
		den[k] = 0;
	for(int i = 0;i < count; i++)
		for(int j = 0;j < count; j++)
		{
			if( distance(p[i],p[j]) <= LITTLE_CIRCLE * LITTLE_CIRCLE)
				den[j]++;
		}
	int *center = new int[255],n = 0;
	for(int m = 0 ; m < 255; m++)
		center[m] = 0;
	center[n] = max_den(count);
	den[ center[n] ] = 0;
	n++;
	int temp;
	bool over;
	do{
		over= false;
         temp = max_den(count);
		 for( int ii = 0; ii < n ; ii++)
			 if( distance(p[center[ii]],p[temp]) <= LARGE_CIRCLE*LARGE_CIRCLE )
				 den[ temp ] = 0;
		 if( den[temp] )
			 center[ n++ ] = temp;
		 for(int jj = 0; jj < count; jj++)
			 if(den[jj]) 
				 over = true;
		if( !over ) break;
	}while(true);
    if( Cw ) delete [] Cw;
	Cw = new C_point[n];
	for(int j1 = 0; j1 < n; j1++)
	{
		Cw[j1].w.x = p[ center[j1] ].x;
		Cw[j1].w.y = p[ center[j1] ].y;
		Cw[j1].num = new int[count];
		Cw[j1].count = 0;
	}
	Cl_k = n;
    KMeans(count,n);
    delete[] center;
}

int Ckmeans::max_den(int count)
{
	bool find ;
	for( int i = 0; i < count ; i++ )
		
	{
		find = true;
		for(int j = 0 ; j < count ; j++)
			if( den[i] < den[j] ) 
			{
				find = false;
				break;
			}
        if( find ) 
			break;
	}
	return i;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -