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

📄 cluster.cpp

📁 该程序通过遗传算法对图像进行聚类分析
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			a+=t1[i]*t2[i];
			b1+=t1[i]*t1[i];
			b2+=t2[i]*t2[i];
		}
		delete	[]t1;
		delete	[]t2;
		if ((b2+b1-a)!=0)
		result=(double)(a/(b1+b2-a));
		else 
		{
			return -1;
		}
		return (1-result);
	}
	else
		return -1;
}
/*************************************************************
*函数名称		GetDistance(CCluster::Center mCenter1,CCluster::Center mCenter2,int distype)
*参数			CCluster::Center mCenter1   中心1
*				CCluster::Center mCenter2   中心2
*				const int distype	         距离模式   1:欧氏距离;2:夹角余弦距离;		
*											            3:特征是二值时的夹角余弦距离;
*														4:具有二值特征的Tanimoto测度
*返回值			double
*函数功能		计算两个聚类中心间的距离,距离模式由distype给定
*************************************************************/
double CCluster::GetDistance(CCluster::Center mCenter1,CCluster::Center mCenter2,int distype)
{
	double result;
	result=0;

	if (distype==1)//欧氏距离
	{
		for ( int m=0;m<N*N;m++)
		result+=(mCenter1.feature[m]-mCenter2.feature[m])*(mCenter1.feature[m]-mCenter2.feature[m]);
		return (double)sqrt(result);
	}
	else if (distype==2)//夹角余弦
	{
		double	a,b1,b2;
		a=0;
		b1=0;
		b2=0;
		for (int i=0; i<N*N; i++)
		{
			a+=mCenter1.feature[i]*mCenter2.feature[i];
			b1+=mCenter1.feature[i]*mCenter1.feature[i];
			b2+=mCenter2.feature[i]*mCenter2.feature[i];
		}
		if (b2*b1!=0)
		result=a/sqrt(b1*b2);
		else 
		{
			return -1;
		}

		return (1-result);
	}
	else if (distype==3)//二值夹角余弦
	{
		int *t1,*t2;
		int a,b1,b2;
		 
		a=0;b1=0;b2=0;
		t1=new int [N*N];
		t2=new int [N*N];
		for(int i=0; i<N*N; i++)
		{
			t1[i]=mCenter1.feature[i]>0.2? 1:0;
			t2[i]=mCenter2.feature[i]>0.2? 1:0;
		}
		
		for ( i=0; i<N*N; i++)
		{
			a+=t1[i]*t2[i];
			b1+=t1[i]*t1[i];
			b2+=t2[i]*t2[i];
		}
		delete	[]t1;
		delete	[]t2;
		if (b2*b1!=0)
		result=(double)(a/sqrt(b1*b2));
		else 
		{
			return -1;
		}

		return (1-result);
	}
	else if (distype==4)//Tanimoto
	{
		int *t1,*t2;
		int a,b1,b2;
		 
		a=0;b1=0;b2=0;
		t1=new int [N*N];
		t2=new int [N*N];
		for(int i=0; i<N*N; i++)
		{
			t1[i]=mCenter1.feature[i]>0.2? 1:0;
			t2[i]=mCenter2.feature[i]>0.2? 1:0;
		}
		
		for ( i=0; i<N*N; i++)
		{
			a+=t1[i]*t2[i];
			b1+=t1[i]*t1[i];
			b2+=t2[i]*t2[i];
		}
		delete	[]t1;
		delete	[]t2;
		if ((b2*b1-a)!=0)
		result=(double)(a/(b1+b2-a));
		else 
		{
			return -1;
		}
		return (1-result);
	}
	else
		return -1;	
}

/************************************************************
*函数名称		GetDistance(double *dis, int i, int j)
*参数			double *dis    指向模糊距离数组的指针大小为[patternnum*patternnum]
*				int i			数组的第i行
*				int j			数组的第j列
*返回值		    double
*函数功能		返回模糊距离数组中第i行第j列的模糊积
*************************************************************/
double CCluster::GetDistance(double *dis, int i, int j)
{
	double result;
	result=0;

	for(int t=0;t<patternnum;t++)
	{
		double td=dis[i*patternnum+t]<dis[t*patternnum+j]? dis[i*patternnum+t]:dis[t*patternnum+j];
		if (result<td)
			result=td;
	}
	return result;
}
/************************************************************
*函数名称		GetFuzzyDistance(CCluster::Pattern pattern1,CCluster::Pattern pattenr2, int distype)
*参数			CCluster::Pattern pattern1    样品1
*				CCluster::Pattern pattern2    样品2
*				int distype					  距离计算形式:1,欧氏距离;2,数量积;
*															3,相关系数
*															4,最大最小法;5,算数平均法; 
*															6,几何平均最小法
*返回值         double
*功能			计算两个样品的模糊距离,距离模式由参数distype给出
************************************************************/
double CCluster::GetFuzzyDistance(CCluster::Pattern pattern1,CCluster::Pattern pattern2, int distype)
{
	switch	(distype)
	{
	case 1://欧氏距离
		{
				double max=0;
				for (int i=0; i<patternnum-1; i++)
					for (int j=i+1; j<patternnum; j++)
						if (max<GetDistance(m_pattern[i],m_pattern[j],1))
							max=GetDistance(m_pattern[i],m_pattern[j],1);
				return (max-GetDistance(pattern1,pattern2,1))/max;
		}
	case 2://数量积
		{
			double temp,max;
			max=0;
			for (int i=0; i<patternnum-1; i++)
				for (int j=0; j<patternnum; j++)
				{
					temp=0;
					for (int k=0; k<N*N; k++)
					{
						temp+=m_pattern[i].feature[k]*m_pattern[j].feature[k];
					}
					if (max<temp)
						max=temp;
				}
			temp=0;
			for ( i=0; i<N*N; i++)
			{
				temp+=pattern1.feature[i]*pattern2.feature[i];
			}
			return (temp/max);
		}
	case 3://相关系数
		{
			double ap1,ap2;
			ap1=0;ap2=0;
			for (int i=0; i<N*N; i++)
			{
				ap1+=pattern1.feature[i];
				ap2+=pattern2.feature[i];
			}
			ap1/=N; 
			ap2/=N;

			double a,b1,b2;
			a=0;b1=0;b2=0;

			for (i=0; i<N*N; i++)
			{
				a+=(pattern1.feature[i]-ap1)*(pattern2.feature[i]-ap2);
				b1+=(pattern1.feature[i]-ap1)*(pattern1.feature[i]-ap1);
				b2+=(pattern2.feature[i]-ap2)*(pattern2.feature[i]-ap2);
			}
			if (b2*b1!=0)
				return (a/sqrt(b1*b2));
		}
	case 4://最大最小法
		{
			double min ,max;
			min=0; max=0;
			for (int i=0; i<N*N; i++)
			{
				min+=pattern1.feature[i]<pattern2.feature[i]? pattern1.feature[i]:pattern2.feature[i];
				max+=pattern1.feature[i]<pattern2.feature[i]? pattern2.feature[i]:pattern1.feature[i];
			}
			if (max!=0)
			return (min/max);
		}
	case 5://算数平均法
		{
			double min ,max;
			min=0; max=0;
			for (int i=0; i<N*N; i++)
			{
				min+=pattern1.feature[i]<pattern2.feature[i]? pattern1.feature[i]:pattern2.feature[i];
				max+=pattern1.feature[i]+pattern2.feature[i];
			}
			if (max!=0)
			return (2*min/max);	
		}
	case 6://几何平均最小法
		{
			double min ,max;
			min=0; max=0;
			for (int i=0; i<N*N; i++)
			{
				min+=pattern1.feature[i]<pattern2.feature[i]? pattern1.feature[i]:pattern2.feature[i];
				max+=sqrt(pattern1.feature[i]*pattern2.feature[i]);
			}
			if (max!=0)
			return (min/max);			
		}
	default:
		return -1;
	}
}


void CCluster::FuzzyCluster()
{
	GetFeature();//获得所有样品特征

	double	*dis, *tempdis;
	double	dismax;
	int		i,j;
	int		distype;
	dismax=0;

	dis=new double [patternnum*patternnum];//模糊系数矩阵
	tempdis=new double [patternnum*patternnum];
	DlgFuzzyDistance  dfd;
	if (dfd.DoModal()==IDOK)
	{
		distype=dfd.mfuzzydistance;
	}
	else 
		return;
    //得到初始模糊距离
	for ( i=0; i<patternnum; i++)
		for (j=0; j<patternnum; j++)
	{
		dis[i*patternnum+j]=GetFuzzyDistance(m_pattern[i],m_pattern[j],distype);//distype
	}

   //构造等价类
	bool flag;
	flag=true;
	while (flag)
	{
		flag=false;
		for ( i=0; i<patternnum; i++)
			for ( j=0; j<patternnum; j++)
				if (i==j)//对角线为1
					tempdis[i*patternnum+j]=1;
				else
					tempdis[i*patternnum+j]=GetDistance(dis,i,j);
		for ( i=0; i<patternnum; i++)
		{
			for ( j=0; j<patternnum; j++)
				if ((tempdis[i*patternnum+j]-dis[i*patternnum+j])*(tempdis[i*patternnum+j]-dis[i*patternnum+j])>0.000001)//(tdis[i][j]!=dis[i][j])
				{
					flag=true;
					break;
				}
			if (flag)
				break;
		}
	
		for ( i=0; i<patternnum*patternnum; i++)
				dis[i]=tempdis[i];
	}
	//输出模糊矩阵
	CString ts,sout;
	//第一行标号1,2,。。。,patternnum。
	sout.Insert(sout.GetLength(),"   \t");
	for (i=1; i<=patternnum; i++)
	{
		ts.Format("%d   \t",i);
		sout.Insert(sout.GetLength(),ts);
	}
	sout.Insert(sout.GetLength(),"\n\n");

	for (i=0; i<patternnum; i++)
	{
		//每列开头标号
		ts.Format("%d   \t",i+1);
		sout.Insert(sout.GetLength(),ts);
		//输出模糊系数矩阵
		for(j=0; j<patternnum; j++)
		{
			ts.Format("%0.3f\t",dis[i*patternnum+j]);
			sout.Insert(sout.GetLength(),ts);
			if ((j+1)%patternnum==0)
				sout.Insert(sout.GetLength(),"\n\n\n");

		}
	}
	MessageBox(NULL,sout,"模糊矩阵",MB_OK);

	delete []tempdis;

	double *xishu=new double [patternnum*patternnum];
	for(i=0; i<patternnum*patternnum; i++)
		xishu[i]=-1;

	int pointer=0;
	//记录模糊系数矩阵中不同的系数
	for ( i=0; i<patternnum; i++)
		for ( j=i; j<patternnum; j++)
		{
			bool done=false;
			for (int k=0; k<pointer; k++)
			{
				if ((xishu[k]-dis[i*patternnum+j])*(xishu[k]-dis[i*patternnum+j])<0.000001)
				{
					done=true;
					break;
				}
			}
			if (!done)
			{
				xishu[pointer]=dis[i*patternnum+j];
				pointer++;
			}
		}
	
	for(i=0; i<pointer-1; i++)//对阈值由小到大排序
		for (j=0; j<pointer-i-1; j++)
		{
			if (xishu[j]>xishu[j+1])
			{
				double	temp=xishu[j];
				xishu[j]=xishu[j+1];
				xishu[j+1]=temp;
			}
		}
	CString s,str;
	for (i=0; i<pointer; i++)
	{
		s.Format("%0.4f  ",xishu[i]);
		str.Insert(str.GetLength(),s);
	}
	delete   []xishu;
	//用户输入聚类阈值
	double    yz;


	
	int *result;
	//根据阈值输出聚类结果
	result=new int [patternnum*patternnum];
	for (i=0; i<patternnum*patternnum; i++)
		if (dis[i]>=yz)
			result[i]=1;
		else 
			result[i]=0;

		//分类后输出

	//第一行标号
	sout="";
	sout.Insert(-1,"每行中\"1\"对应的列为同一类");
	sout.Insert(sout.GetLength(),"\n\n");
	sout.Insert(sout.GetLength(),"   \t");
	for (i=1; i<=patternnum; i++)
	{
		ts.Format("%d   \t",i);
		sout.Insert(sout.GetLength(),ts);
	}
	sout.Insert(sout.GetLength(),"\n\n");
		

	for (i=0; i<patternnum; i++)
	{
		//每列开头标号
		ts.Format("%d   \t",i+1);
		sout.Insert(sout.GetLength(),ts);
		for(j=0; j<patternnum; j++)//首行为原模糊系数
		{
			ts.Format("%0.3f\t",dis[i*patternnum+j]);
			sout.Insert(sout.GetLength(),ts);
			if ((j+1)%patternnum==0)
				sout.Insert(sout.GetLength(),"\n");
		}
		sout.Insert(sout.GetLength(),"   \t");
		for(j=0; j<patternnum; j++)//次行为根据阈值修改后的系数“1”或“0”
		{
			ts.Format("%d\t",result[i*patternnum+j]);
			sout.Insert(sout.GetLength(),ts);
			if ((j+1)%patternnum==0)
				sout.Insert(sout.GetLength(),"\n\n");
		}
	}
	MessageBox(NULL,sout,"分类前后的矩阵对照",MB_OK);

	centernum=0;

	for (i=0; i<patternnum; i++)//按照阈值分类
		for (j=i; j<patternnum; j++)
		{
			if (result[i*patternnum+j]==1)
			{
				if (m_pattern[i].category!=0)
					m_pattern[j].category=m_pattern[i].category;
				else if (m_pattern[j].category!=0)
					m_pattern[i].category=m_pattern[j].category;
				else
				{
					centernum++;
					m_pattern[j].category=centernum;
					m_pattern[i].category=centernum;
				}
			}
		}
	delete []dis;
	delete []result;
}




⌨️ 快捷键说明

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