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

📄 patternview.cpp

📁 本人的模式识别课程VC源程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	delete [] yangbenzhx;
    //重画视图
	OnDraw(pDC);

	// 恢复光标
	EndWaitCursor();
	
	
}



void CPatternView::OnThreshold() 
{
	// TODO: Add your command handler code here
///////////////////////////////////////////////////////////////////////////////////////////////
 // bshowcen = true;
	CDC* pDC;
	pDC=GetDC();
	int i, j, k;
	float distance;
	float olddis , newdis;
    float sumcencx[10] = {0,0,0,0,0,0,0,0,0,0};
	float sumcency[10] = {0,0,0,0,0,0,0,0,0,0};
	int   sumnum[10] = {0,0,0,0,0,0,0,0,0,0};
	CString str;

	//初始化所有样本点的颜色
	for(i=0;i<iShuMu;i++)   
	{
		for(j=0;j<iDianShu;j++)
		{
			samplenum[i*iDianShu+j].colorvalue = RGB(255,0,0);
		}
	}
	//开始搜索,初始化所有未归类的样本点
	for(i=0;i<iShuMu;i++)   
	{
		for(j=0;j<iDianShu;j++)
		{
			samplenum[i*iDianShu+j].fseek = false;
		}
	}

/////////////////(循环体部份)/////////////////////////////////////////////////////////////////////////
		//第一步:选择第一样本点为第一中心点
	samplecen[0] = samplenum[0];
	for(k = 0; k < iShuMu ; k++)
	{
		//第二步:搜索第一样本点为中心的第一类中的样本,阈值为类内T        
        sumcencx[k]=0;
		sumcency[k]=0;
		sumnum[k]=0;

	    for(i = 0; i < iShuMu*iDianShu; i++)
		{
			if(!samplenum[i].fseek)//初始化所有未归类的样本点samplenum[i].fseek = false;
			//!samplenum[i].fseek为真即samplenum[i].fseek = false也就是所有未归类的样本点
			{
				distance = sqrt((samplenum[i].cx - samplecen[k].cx)*(samplenum[i].cx - samplecen[k].cx) 
				             + (samplenum[i].cy - samplecen[k].cy)*(samplenum[i].cy - samplecen[k].cy));
				if(distance < 80)
				{    
					 samplenum[i].k = k;
                     samplenum[i].colorvalue = RGB(255*3/(k+1)%255,255*14/(k+1)%255,255*21/(k+1)%255);
				     samplenum[i].fseek = true;
	                 sumcencx[k]=samplenum[i].cx+sumcencx[k];
					 sumcency[k]=samplenum[i].cy+sumcency[k];
					 sumnum[k]++;


				}
			 }
		}
		//修改中心

        sumcencx[k] = sumcencx[k]/sumnum[k];
		sumcency[k] = sumcency[k]/sumnum[k];

		if(sumcencx[k]!=samplecen[k].cx || sumcency[k]!=samplecen[k].cy)
		{
			samplecen[k].cx=sumcencx[k];
			samplecen[k].cy=sumcency[k];
			for(i = 0;i < iShuMu*iDianShu; i++)//将已归类的点置为未归类的点重新以新的中心点归类
			{
				if(samplenum[i].k==k)
					samplenum[i].fseek = false;
			}
			k--;
			continue;//结束本次循环,接着开始判断决定是否继续执行下一次循环
		}
//////////////////////////////////////////////////////////////////////////////////////////
       samplecen[k].fseek=true;
        //是否显示中心点
		bshowcen = true;
       OnDraw(pDC);  
    	//显示文本
	        CFont MyFont;
	        MyFont.CreateFont(25,0,0,0,400,FALSE,FALSE,0,
		                       ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
		                       DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"楷体_GB2312");
	        CFont* pOldFont=pDC->SelectObject(&MyFont);
            pDC->SetBkMode(TRANSPARENT);
	        pDC->SetTextColor(RGB(255,0,255));
            str="  阈值T=80";
			pDC->TextOut(650,20,str);
	        char number[80];
			sprintf(number,"  第%d个聚类中心点!",k+1);
			pDC->TextOut(300,20,number);
	        MyFont.DeleteObject();           
	         Sleep(1000);//
//////////////////////////////////////////////////////////////////////////////////
		//找出与第一类中心距离最远的未归类的样本点samplenum[i]作为下一个中心点samplecen[k+1]
		olddis = 0;
		for(i = 0; i < iShuMu*iDianShu; i++)//所有未归类的点
		{
			if(!samplenum[i].fseek)
			{
				newdis = sqrt((samplenum[i].cx - samplecen[k].cx)*(samplenum[i].cx - samplecen[k].cx) 
				            + (samplenum[i].cy - samplecen[k].cy)*(samplenum[i].cy - samplecen[k].cy));
				
			    if(newdis > olddis)
				{
					olddis = newdis;
					if(k + 1 < iShuMu && olddis > 80)
						samplecen[k+1] = samplenum[i];//将最远的点作为下一个中心点
				}


			 }
		}

	}

   // for(i=0;i < 10;i++)
	//{
//		samplecen[i].fseek = true;
//	}
	bshowcen = false; 
}

void CPatternView::OnMaxiMin() 
{
	// TODO: Add your command handler code here
	bshowcen = true;
	CDC* pDC;
	pDC=GetDC();

	int i, j, k, m, precenter;
	float maxdis;
    float olddis[1500] , newdis;
	float sumdis;
    
	//初始化所有样本点的颜色
	for(i=0;i<iShuMu;i++)   
	{
		for(j=0;j<iDianShu;j++)
		{
			samplenum[i*iDianShu+j].colorvalue = RGB(255,0,0);//在::OnMoBanSet()中随机数据
	                                                          //存放于samplenum[i*iDianShu+j]中
		}
	}
	//初始化所有未归类的样本点
	for(i=0;i<iShuMu;i++)   
	{
		for(j=0;j<iDianShu;j++)
		{
			samplenum[i*iDianShu+j].fseek = false;
		}
	}
	
	//第一步:选择第一样本点为第一中心点
	samplecen[0] = samplenum[0];
	samplenum[0].fseek = true;
	samplenum[0].k = 0;


	//第二步:确定距离第一中心点最远的点为第二中心点
	olddis[0] = 0;
	for(i = 0; i < iShuMu*iDianShu; i++)
	{
			newdis = sqrt((samplenum[i].cx - samplecen[0].cx)*(samplenum[i].cx - samplecen[0].cx) 
			            + (samplenum[i].cy - samplecen[0].cy)*(samplenum[i].cy - samplecen[0].cy));
			
		    if(newdis > olddis[0])
			{
				olddis[0] = newdis;
				samplecen[1] = samplenum[i];
				k=i;//与所属类的“K”不一样
				
			}
			
	}
	samplenum[k].fseek = true;
	samplenum[k].k = 1;

    //第三步:计算样本到各个样本中心的平均距离,并且小中取大
	
	for(i = 0; i < iShuMu*iDianShu; i++)
	{
		olddis[i] = 2000;
	}
    for(m = 2; m < iShuMu; m++)//由于已有第一中心点即第0类,第二中心点即第1类,故m从第2类开始寻找第三中心点
	{
		maxdis = 0;
    	for(i = 0; i < iShuMu*iDianShu; i++)
		{
			if(!samplenum[i].fseek)
			{
				
	        	for(j = 0; j < m; j++)//未归类的每一点到已确定的各个样本中心的距离newdis,并找到最小的距离放置于olddis[i]中
				{
	       			newdis = sqrt((samplenum[i].cx - samplecen[j].cx)*(samplenum[i].cx - samplecen[j].cx) 
			             + (samplenum[i].cy - samplecen[j].cy)*(samplenum[i].cy - samplecen[j].cy));
		       	    if(newdis < olddis[i])
					{
		     			olddis[i] = newdis; //olddis[i]存放第i个未归类的样本点到各个已确定的样本中心点的距离中的最小值   
					}
		 
				}//即计算表四中每一行,olddis[i]放置每一行的最小值
		        if(maxdis < olddis[i])//找出距离中最小值中的最大值放置于maxdis即在表四所有行中找到最大的
				{
	           		maxdis = olddis[i];
	        		precenter = i;//记下该样本点放置于precenter作为可能的中心点
				}//即计算表四中第一列的最大值
			}
			
		}
		
	   //第四步:判断其他中心(判断可能的中心点是否为中心点)
		sumdis = 0;
		k = 0;
		for(i = 0; i < m; i++)//i为已分出的第一中心点即第0类,第二中心点即第1类...第m-1类
		{
			for(j = 0; j < m; j++)//每一已确定中心点与其它已确定中心点的距离分别相加并放置于sumdis中并统计个数,以便求这些距离的均值
			{
				if(i != j)
				{
			    	newdis = sqrt((samplecen[i].cx - samplecen[j].cx)*(samplecen[i].cx - samplecen[j].cx) 
			                + (samplecen[i].cy - samplecen[j].cy)*(samplecen[i].cy - samplecen[j].cy));
					sumdis += newdis;
					k++;
				}
			}
		}
		sumdis /= k;//sumdis=sumdis/k求这些距离的均值
		if(maxdis > sumdis/3)
		{
			samplecen[m] = samplenum[precenter];
			samplenum[precenter].fseek = true;
			samplenum[precenter].k = m;

		}
		else
			break;
	}
	//第五步:分配样本到各中心点
	for(i = 0; i < iShuMu*iDianShu; i++)
	{   
		//搜索非中心点的样本点到各中心点的最小距离作为聚类的标准		
		olddis[0] = 2000;
		
		for(k = 0; k < iShuMu; k++)
		{
			
			if(!samplenum[i].fseek)	//!samplenum[i].fseek为除中心点之外所有未归类的点,求每一未归
//类的样本点到所有中心点的距离并求其最小距离存放于olddis[0]中,并将该样本点进行归类、着色。
//注意:并没有给已归类的样本点设置标志为true,即类似为已确定的中心点设置标志:samplenum[precenter].fseek = true;		
			{   
				
				newdis = sqrt((samplenum[i].cx - samplecen[k].cx)*(samplenum[i].cx - samplecen[k].cx) 
			            + (samplenum[i].cy - samplecen[k].cy)*(samplenum[i].cy - samplecen[k].cy));			
		        if(newdis < olddis[0])
				{
			    	olddis[0] = newdis;
			        samplenum[i].k = k;//k为样本点归属的类
				    samplenum[i].colorvalue = RGB(255*3/(k+1)%255,255*14/(k+1)%255,255*21/(k+1)%255);
				}
			}
		}
//中心点特殊处理。注意:samplenum[i].fseek为已确定的中心点,samplecen[m] = samplenum[precenter];samplenum[precenter].fseek = true;
//而其它的随机样本点(包括已归类的样本点)都没有设置标志。			 
		if(samplenum[i].fseek)//samplenum[i].fseek为已确定的中心点
		{
			m = samplenum[i].k;//samplenum[precenter].k = m;m为中心点归属的类

			samplenum[i].colorvalue = RGB(255*3/(m+1)%255,255*14/(m+1)%255,255*21/(m+1)%255);			
		}
	}
	
	//第六步:修改中心
	float sumcencx[10] = {0,0,0,0,0,0,0,0,0,0};//一共为10类
	float sumcency[10] = {0,0,0,0,0,0,0,0,0,0};
	int   sumnum[10] = {0,0,0,0,0,0,0,0,0,0};
	
	for(i = 0; i < iShuMu*iDianShu; i++)//找出每一类的所有样本点并求均值作为第个类新的聚类中心
	{
		for(k = 0; k < iShuMu; k++)
		{
			if(samplenum[i].k == k)//找出每一随机样本点所属的类
			{
				sumcencx[k] = samplenum[i].cx + sumcencx[k];
			    sumcency[k] = samplenum[i].cy + sumcency[k];
			    sumnum[k]++;//将数组sumnum[10]的第k个数组元素的值加“1”而不是指向下一个数组元素
			}
		}
	}
	for(k = 0; k < iShuMu; k++)//求均值作为第个类新的聚类中心
	{
		samplecen[k].cx = sumcencx[k]/sumnum[k];
        samplecen[k].cy = sumcency[k]/sumnum[k];
	}
    //初始化样本中心点是否显示,用于中心点以“+”显示
    for(i=0;i < 10;i++)
	{
		samplecen[i].fseek = true;
	}
	OnDraw(pDC);
	

	
}

void CPatternView::OnKMeans() 
{
	// TODO: Add your command handler code here
bshowcen = true;
	CDC* pDC;
	pDC=GetDC();
	
	int i, j ,k;
	SampleDot *oldprecen;
	oldprecen = new SampleDot[10];
	float olddis , newdis;

	//初始化所有样本点的颜色
	for(i=0;i < iShuMu;i++)   
	{
		for(j=0;j < iDianShu;j++)
		{
			samplenum[i*iDianShu+j].colorvalue = RGB(255,0,0);
		}
	}
	//初始化所有未归类的样本点
	for(i=0;i<iShuMu;i++)   
	{
		for(j=0;j<iDianShu;j++)
		{
			samplenum[i*iDianShu+j].fseek = false;
		}
	}
	//第一步:选择样本点前K=iShuMu个为预测类中心
	for(i=0;i < iShuMu;i++)
	{
		oldprecen[i] = samplenum[i];
	}
    //第二步:逐个将样本点按最小距离原则分配到旧的样本中心
	int n = 0;
lab1:
	n++;
	for(i=0;i<iShuMu * iDianShu;i++)
	{
		olddis = 2000;
		for(j=0;j < iShuMu;j++)
		{
			
			newdis = sqrt((samplenum[i].cx - oldprecen[j].cx) * (samplenum[i].cx - oldprecen[j].cx) 
			            + (samplenum[i].cy - oldprecen[j].cy) * (samplenum[i].cy - oldprecen[j].cy));
			if(newdis < olddis)
				{
			    	olddis = newdis;
			        samplenum[i].k = j;
				    samplenum[i].colorvalue = RGB(255*3/(j+1)%255,255*14/(j+1)%255,255*21/(j+1)%255);
				}
			
		}
	}
	//第三步:修改聚类中心
	float sumcencx[10] = {0,0,0,0,0,0,0,0,0,0};
	float sumcency[10] = {0,0,0,0,0,0,0,0,0,0};
	int   sumnum[10] = {0,0,0,0,0,0,0,0,0,0};	
	for(i = 0; i < iShuMu*iDianShu; i++)
	{
		for(k = 0; k < iShuMu; k++)
		{
			if(samplenum[i].k == k)
			{
				sumcencx[k] = samplenum[i].cx + sumcencx[k];
			    sumcency[k] = samplenum[i].cy + sumcency[k];
			    sumnum[k]++;
			}
		}

⌨️ 快捷键说明

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