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

📄 k_averagedoc.cpp

📁 简单的模式识别的分类算法(K_均值算法),包含样本数据和实验结果。
💻 CPP
字号:
// K_averageDoc.cpp : implementation of the CK_averageDoc class
//

#include "stdafx.h"
#include "K_average.h"

#include "K_averageDoc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CK_averageDoc

IMPLEMENT_DYNCREATE(CK_averageDoc, CDocument)

BEGIN_MESSAGE_MAP(CK_averageDoc, CDocument)
	//{{AFX_MSG_MAP(CK_averageDoc)
	ON_COMMAND(ID_MENUI_KAVERAGE, OnMenuiKaverage)
	ON_COMMAND(ID_MENUI_SAVE_CLASSRESULT, OnMenuiSaveClassresult)
	ON_COMMAND(ID_MENUI_RESET, OnMenuiReset)
	ON_COMMAND(ID_MENUI_SAVERESULT, OnMenuiSaveresult)
	ON_COMMAND(ID_MENUI_DUOLEI, OnMenuiDuolei)
	ON_COMMAND(ID_MENUI_MULTIEPYSAVE, OnMenuiMultiepysave)
	ON_COMMAND(ID_MENUI_HELP, OnMenuiHelp)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CK_averageDoc construction/destruction

CK_averageDoc::CK_averageDoc()
{
	// TODO: add one-time construction code here

}

CK_averageDoc::~CK_averageDoc()
{
}

BOOL CK_averageDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CK_averageDoc serialization

void CK_averageDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CK_averageDoc diagnostics

#ifdef _DEBUG
void CK_averageDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CK_averageDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CK_averageDoc commands

BOOL CK_averageDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	FILE *file_swatch;   //实验数据文件文件
	file_swatch=fopen(lpszPathName,"rt"); //以读的方式打开样本文件
	int num_swatch,num_class;			//实验数据数目和类别数目
	if (file_swatch==NULL)
	{
		AfxMessageBox("文件不能正常打开!",MB_OKCANCEL,NULL);
		return false;
	}
	fscanf(file_swatch,"%d%d",&num_swatch,&num_class);
	for (int i=0;i<num_swatch;i++)
	{
		fscanf(file_swatch,"%d%d",&feature_point.x,&feature_point.y);
		vec_feature_point.push_back(feature_point);

	}
	UpdateAllViews(NULL);
	
	// TODO: Add your specialized creation code here
	fclose(file_swatch);
	return TRUE;
}

void CK_averageDoc::OnMenuiKaverage() 
{
	BOOL flags=FALSE;
	CPoint m_ptz1; //第一类初始中心
	CPoint m_ptz2;//第二类初始中心
	CPoint m_pt_tmp;
	m_ptz1=vec_feature_point[0];//赋初始值
	m_ptz2=vec_feature_point[1];
	vec_point1.push_back(m_ptz1);
	vec_point2.push_back(m_ptz2);
	float x1,y1,x2,y2;			//the center coordinate(x,y) of the two class
	float x1_tmp,y1_tmp,x2_tmp,y2_tmp;//中心临时变量 
	float dist1,dist2; //the distance to the center of the two class
	HCURSOR m_hcur;
	m_hcur=::SetCursor(LoadCursor(NULL,IDC_WAIT));
	x1=m_ptz1.x;y1=m_ptz1.y;//中心初始赋值
	x2=m_ptz2.x;y2=m_ptz2.y;//中心初始赋值
	vec_point_class.clear();
	do 
	{
		for (int i=0;i<vec_feature_point.size();i++)
		{	
			dist1=(x1-vec_feature_point[i].x)*(x1-vec_feature_point[i].x)+
				(y1-vec_feature_point[i].y)*(y1-vec_feature_point[i].y);
			dist2=(x2-vec_feature_point[i].x)*(x2-vec_feature_point[i].x)+
				(y2-vec_feature_point[i].y)*(y2-vec_feature_point[i].y);
			m_pt_tmp.x=vec_feature_point[i].x;
			m_pt_tmp.y=vec_feature_point[i].y;
			if (dist1<=dist2) 
			{
			
				vec_point1.push_back(m_pt_tmp);
			}
			else
			{
				vec_point2.push_back(m_pt_tmp);

			}

		}
		float total1=0;float total2=0;
		for (int m=0;m<vec_point1.size();m++)
		{	
			total1+=vec_point1[m].x;
			total2+=vec_point1[m].y;
		}
		int num_vec1;
		num_vec1=vec_point1.size();
		x1_tmp=total1/num_vec1;
		y1_tmp=total2/num_vec1;

		float total3=0;float total4=0;
		for (int n=0;n<vec_point2.size();n++)
		{
			total3+=vec_point2[n].x;
			total4+=vec_point2[n].y;
		}
		int num_vec2;
		num_vec2=vec_point2.size();
		x2_tmp=total3/num_vec2;
		y2_tmp=total4/num_vec2;

		if (x1!=x1_tmp||y1!=y1_tmp||x2!=x2_tmp||y2!=y2_tmp) 
		{
			x1=x1_tmp;y1=y1_tmp;x2=x2_tmp;y2=y2_tmp;
			vec_point2.clear();
			vec_point1.clear();
			flags=true;	
		}
		else
		{
			flags=false;
		}
	} 
	while(flags);


	::SetCursor(m_hcur);
	UpdateAllViews(NULL);
}

BOOL CK_averageDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	// TODO: Add your specialized code here and/or call the base class
	FILE *vec_file;
	vec_file=fopen(lpszPathName,"wt");
	int num_swatch,num_class=2;
	num_swatch=vec_feature_point.size();
	fprintf(vec_file,"%d  %d\n",num_swatch,num_class);
	for (int i=0;i<vec_feature_point.size();i++)
	{
		fprintf(vec_file,"%d  %d\n",vec_feature_point[i].x,vec_feature_point[i].y);
	}

	fclose(vec_file);
	return true;
//	return CDocument::OnSaveDocument(lpszPathName);
}

void CK_averageDoc::OnMenuiSaveClassresult() 
{
	// TODO: Add your command handler code here
	CFileDialog save_result_filedlg(FALSE,"txt",NULL,0,"(文本文件*.txt)|*.txt|DATA型文件(*.dat)|*.dat|所有文件(*.*)|*.*||",NULL);
	CString  sav_filname;
	LPCTSTR lpszPathName;
	FILE *sav_result_file;
	int num_vec_point1,num_vec_point2,num_total;
	int num_class=2;
	num_total=vec_feature_point.size();
	num_vec_point1=vec_point1.size();
	num_vec_point2=vec_point2.size();
	if (save_result_filedlg.DoModal()==IDOK) 
	{
		sav_filname=save_result_filedlg.GetPathName();
		 lpszPathName=(LPCTSTR)sav_filname;
		sav_result_file=fopen(lpszPathName,"wt");
		fprintf(sav_result_file,"/**********************************************************************************/\n\n");
		fprintf(sav_result_file,"           /*版权所有*/\n           /*盗版不究*/\n          /\n\n");
		fprintf(sav_result_file,"/**********************************************************************************/\n\n");
		fprintf(sav_result_file,"样本总个数为:%d\n样本分成了%d类\n第一类的样本个数为:%d\n特征向量具体如下:\n",num_total,num_class,num_vec_point1);
		for (int i=0;i<vec_point1.size();i++)
		{
			fprintf(sav_result_file,"%d  %d\n",vec_point1[i].x,vec_point1[i].y);
		}
		fprintf(sav_result_file,"第二类样本个数为:%d\n特征向量具体如下:\n",num_vec_point2);
		for (int j=0;j<vec_point2.size();j++) 
		{
			fprintf(sav_result_file,"%d  %d\n",vec_point2[j].x,vec_point2[j].y);
		}
		fclose(sav_result_file);
		return;
	}
	else if (save_result_filedlg.DoModal()==IDCANCEL) 
	{
		return;
	}


}

void CK_averageDoc::OnMenuiReset() 
{
	// TODO: Add your command handler code here
	vec_point2.clear();
	vec_point1.clear();
	vec_feature_point.clear();
	vec_point_class.clear();
	UpdateAllViews(NULL);
}

void CK_averageDoc::OnMenuiSaveresult() 
{
	// TODO: Add your command handler code here
	CFileDialog save_result_filedlg(FALSE,"txt",NULL,0,"(文本文件*.txt)|*.txt|DATA型文件(*.dat)|*.dat|所有文件(*.*)|*.*||",NULL);
	CString  sav_filname;
	LPCTSTR lpszPathName;
	FILE *sav_result_file;
	int num_vec_point1,num_vec_point2,num_total;
	int num_class=2;
	num_total=vec_feature_point.size();
	num_vec_point1=vec_point1.size();
	num_vec_point2=vec_point2.size();
	if (save_result_filedlg.DoModal()==IDOK) 
	{
		sav_filname=save_result_filedlg.GetPathName();
		 lpszPathName=(LPCTSTR)sav_filname;
		sav_result_file=fopen(lpszPathName,"wt");
		fprintf(sav_result_file,"/**********************************************************************************/\n\n");
		fprintf(sav_result_file,"           /*版权所有*/\n           /*盗版不究*/\n          /\n\n");
		fprintf(sav_result_file,"/**********************************************************************************/\n\n");
		fprintf(sav_result_file,"样本总个数为:%d\n样本分成了%d类\n第一类的样本个数为:%d\n特征向量具体如下:\n",num_total,num_class,num_vec_point1);
		for (int i=0;i<vec_point1.size();i++)
		{
			fprintf(sav_result_file,"%d  %d\n",vec_point1[i].x,vec_point1[i].y);
		}
		fprintf(sav_result_file,"第二类样本个数为:%d\n特征向量具体如下:\n",num_vec_point2);
		for (int j=0;j<vec_point2.size();j++) 
		{
			fprintf(sav_result_file,"%d  %d\n",vec_point2[j].x,vec_point2[j].y);
		}
		
	}
	fclose(sav_result_file);
}
/*
解决分成多类的问题,可以动态更改分成的类别
*/
void CK_averageDoc::OnMenuiDuolei() 
{
	// TODO: Add your command handler code here
	BOOL flags=FALSE;
	CPoint m_pt_tmp;
	CclassDlg m_classdlg;
	HCURSOR m_hcur;
	vec_point2.clear();
	vec_point1.clear();
	if (m_classdlg.DoModal()==IDOK)
	{
		m_class_num=m_classdlg.m_numclass;
		m_first_center=m_classdlg.m_center;
		float *x1= new float[m_class_num];
		float*y1=new float[m_class_num];			//the center coordinate(x,y) of the two class
		float *x1_tmp=new float[m_class_num];
		float *y1_tmp=new float[m_class_num];//中心临时变量 
//		Cvec_pt1 *vec_mypt=new Cvec_pt1[m_class_num];
		m_hcur=::SetCursor(LoadCursor(NULL,IDC_WAIT));
		for (int num=0;num<m_class_num;num++)//获取初始特征中心
		{
			x1[num]=vec_feature_point[num+m_first_center-1].x;
			y1[num]=vec_feature_point[num+m_first_center-1].y;
		}
		do 
		{	
			vec_point_class.resize(m_class_num);
			for (int i=0;i<vec_feature_point.size();i++)
			{
				float *dist=new float[m_class_num]; //the distance to the center of the two class
				for (int j=0;j<	m_class_num;j++)
				{
					dist[j]=(x1[j]-vec_feature_point[i].x)*(x1[j]-vec_feature_point[i].x)+
						(y1[j]-vec_feature_point[i].y)*(y1[j]-vec_feature_point[i].y);//计算到中心距离
					m_pt_tmp.x=vec_feature_point[i].x;						//获取样本特征向量
					m_pt_tmp.y=vec_feature_point[i].y;
				}
				float dist_tmp=dist[0];
				int dist_min_hao;
				for (int k=0;k<m_class_num;k++)					//遍历所有类别
				{	
					if (dist[k]<=dist_tmp)						//比较到各个类别中心的距离
					{
						dist_tmp=dist[k];
						dist_min_hao=k;                          //记录符合要求类别号
						
					}

				}
				delete[]dist;
				vec_point_class[dist_min_hao].push_back(m_pt_tmp); //将样本插入到符合要求的类别中

			}
			float *total1=new float[m_class_num];
			float *total2=new float[m_class_num];
			memset(total1,0,m_class_num*sizeof(float));            //设置初始值为零
			memset(total2,0,m_class_num*sizeof(float));

			flags=FALSE;//标志中心是否改变,初始状态为未改变
			for (int vec1_num=0;vec1_num<m_class_num;vec1_num++)	//遍历所有样本类别
			{
				for (int m=0;m<vec_point_class[vec1_num].size();m++)
				{	total1[vec1_num]+=vec_point_class[vec1_num][m].x;//样本特征求和
					total2[vec1_num]+=vec_point_class[vec1_num][m].y;
				}
				int num_vec1;
				num_vec1=vec_point_class[vec1_num].size(); //计算某一类中样本数量
				x1_tmp[vec1_num]=total1[vec1_num]/num_vec1;//计算新的中心
				y1_tmp[vec1_num]=total2[vec1_num]/num_vec1;

				if (x1[vec1_num]!=x1_tmp[vec1_num]||y1[vec1_num]!=y1_tmp[vec1_num]) //检查中心是否更改
				{
					x1[vec1_num]=x1_tmp[vec1_num];
					y1[vec1_num]=y1_tmp[vec1_num];
					vec_point_class[vec1_num].clear();  //清除小容器中的样本数据
					flags=true;	
				}
//				else{flags=false;}
			}
			if (flags==TRUE) 	{vec_point_class.clear();} //把大容器中的所有小容器清空
			delete[]total1;//删除变量
			delete[]total2;

		} 
		while(flags);
		::SetCursor(m_hcur);    //恢复光标
		delete[]x1;delete []y1; //删除变量
		delete[]x1_tmp;delete []y1_tmp;

	}



	UpdateAllViews(NULL);

}
//////////////////////////////////////////////////////////////////////////
/* 
save the result of classfication
*/
void CK_averageDoc::OnMenuiMultiepysave() 
{
	// TODO: Add your command handler code here
		CFileDialog save_result_filedlg(FALSE,"txt",NULL,0,"(文本文件*.txt)|*.txt|DATA型文件(*.dat)|*.dat|所有文件(*.*)|*.*||",NULL);
	CString  sav_filname;
	LPCTSTR lpszPathName;
	FILE *sav_result_file;
	int num_vec_point,num_vec;
	num_vec_point=vec_feature_point.size();
	num_vec=vec_point_class.size();
	if (save_result_filedlg.DoModal()==IDOK) 
	{
		sav_filname=save_result_filedlg.GetPathName();
		 lpszPathName=(LPCTSTR)sav_filname;
		sav_result_file=fopen(lpszPathName,"wt");
		fprintf(sav_result_file,"/**********************************************************************************/\n\n");
		fprintf(sav_result_file,"           /*版权所有*/\n           /*盗版不究*/\n          /\n\n");
		fprintf(sav_result_file,"/**********************************************************************************/\n\n");
		fprintf(sav_result_file,"样本总个数为:%d\n分成的类别数目为:%d\n\n",num_vec_point,num_vec);
		for (int i=0;i<vec_point_class.size();i++) 
		{
			fprintf(sav_result_file,"/////////////////////////////////////////////////////////////////////////////////\n");
			fprintf(sav_result_file,"这第%d类样本具体结果如下:\n本类样本数量为:%d\n特征向量为:\n",i+1,vec_point_class[i].size());
			for (int j=0;j<vec_point_class[i].size();j++)
			{
				fprintf(sav_result_file,"%d  %d\n",vec_point_class[i][j].x,vec_point_class[i][j].y);
			}
				
		}
	}
	fclose(sav_result_file);
}

void CK_averageDoc::OnMenuiHelp() 
{
	// TODO: Add your command handler code here
	ShellExecute(NULL,"open","帮助文件.CHM",NULL,NULL,SW_SHOW);
}

⌨️ 快捷键说明

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