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

📄 cluster.cpp

📁 用VISUALC++编写的聚类分析程序,图像识别.(各种算法),具有非常大的价值.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		{
			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; 
			ap1/=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;
	}
}

/************************************************************
*函数名称		Zuilinjinguize()
*参数			void
*返回值		    void
*函数功能		按照最临近规则对全体样品进行分类
************************************************************/
void CCluster::Zuilinjinguize()//最临近规则
{
	GetFeature();

	double  T;//阈值
	int		distype;//距离模式(欧氏、余弦。。。)
	int     i,j;

///////////////输出阈值参考值/////////////////////
	double minous,maxous,mincos,maxcos,minbcos,maxbcos,mintan,maxtan;

	minous=MAX; mincos=MAX; minbcos=MAX; mintan=MAX;
	maxous=0; maxcos=0; maxbcos=0; maxtan=0;

	for (  i=0;i<patternnum-1;i++)//计算四种距离模式的参考值
		for ( j=i+1;j<patternnum;j++)
		{
			if (minous>GetDistance(m_pattern[i],m_pattern[j],1))
				minous=GetDistance(m_pattern[i],m_pattern[j],1);
			if (maxous<GetDistance(m_pattern[i],m_pattern[j],1))
				maxous=GetDistance(m_pattern[i],m_pattern[j],1);

			if (mincos>GetDistance(m_pattern[i],m_pattern[j],2))
				mincos=GetDistance(m_pattern[i],m_pattern[j],2);
			if (maxcos<GetDistance(m_pattern[i],m_pattern[j],2))
				maxcos=GetDistance(m_pattern[i],m_pattern[j],2);

			if (minbcos>GetDistance(m_pattern[i],m_pattern[j],3))
				minbcos=GetDistance(m_pattern[i],m_pattern[j],3);
			if (maxbcos<GetDistance(m_pattern[i],m_pattern[j],3))
				maxbcos=GetDistance(m_pattern[i],m_pattern[j],3);
			
			if (mintan>GetDistance(m_pattern[i],m_pattern[j],4))
				mintan=GetDistance(m_pattern[i],m_pattern[j],4);
			if (maxtan<GetDistance(m_pattern[i],m_pattern[j],4))
				maxtan=GetDistance(m_pattern[i],m_pattern[j],4);
		}
	DlgInfor mDlgInfor;
	mDlgInfor.ShowInfor(minous,maxous,mincos,maxcos,minbcos,maxbcos,mintan,maxtan);

////////////////////////读入阈值和距离形式///////////////
	if (mDlgInfor.DoModal()==IDOK)
	{
		T=mDlgInfor.m_T;
		distype=mDlgInfor.m_DisType;
	}
	else return;
	centernum=1;
	m_center=new Center[patternnum];

    //将第一个样品作为第一个中心
	for ( i=0;i<N*N;i++)
		m_center[0].feature[i]=m_pattern[0].feature[i];
	m_center[0].index=1;
	m_center[0].patternnum=1;
	m_pattern[0].category=1;

	for ( i=1;i<patternnum;i++)//对所有模版进行归类
	{
		double centerdistance=MAX;
		int index=1;
		//找到距离最近的中心index,记录最小距离centerdistance
		for (int j=0;j<centernum;j++)
		{	
			double dis= GetDistance(m_pattern[i],m_center[j],distype);
			if (dis<centerdistance)
			{
				centerdistance=dis;
				index=j;
			}
		}

		if (centerdistance<T)//距离小于阈值则将样品归入该类
		{
			m_pattern[i].category=m_center[index].index;
			CalCenter(&m_center[j]);
		}
		else //新建聚类中心
		{
			centernum++;
			m_pattern[i].category=centernum;
			for (int m=0;m<N*N;m++)
				m_center[centernum-1].feature[m]=m_pattern[i].feature[m];
			m_center[centernum-1].index=centernum;
		}
	}//end of all pattern
	delete []m_center;
}


/************************************************************
*函数名称		Zuidazuixiaojulifa()
*参数			void
*返回值		void
*函数功能		按照最大最小距离规则对全体样品进行分类
************************************************************/
void CCluster::Zuidazuixiaojulifa()
{
	GetFeature();

	int	distype;//距离的形式(欧氏、余弦。。。)
	int i,j;

	DlgInfor mDlgInfor;
	mDlgInfor.ShowInfor(1);
	if (mDlgInfor.DoModal()==IDOK)
	{
		distype=mDlgInfor.m_DisType;
	}
	else return;
	
	double maxdistance=0;//记录两类间的最大距离,用做类分割阈值

	int index=1;//记录距离第一个中心最远的样品

	m_center=new Center[patternnum];

	for ( i=0;i<N*N;i++)//第一个聚类中心
		m_center[0].feature[i]=m_pattern[0].feature[i];
	m_center[0].index=1;
	m_pattern[0].category=1;

	for( i=1;i<patternnum;i++)//第二个聚类中心
		if (maxdistance<GetDistance(m_pattern[i],m_center[0],distype))
		{
			maxdistance=GetDistance(m_pattern[i],m_center[0],distype);
			index=i;
		}
	for ( i=0;i<N*N;i++)//第二个聚类中心
		m_center[1].feature[i]=m_pattern[index].feature[i];
	
	m_center[1].index=2;
	m_pattern[index].category=2;

	centernum=2;

	for ( i=1;i<patternnum;i++)//对所有模板分类
	{
		
		double tdistance=MAX;
		index=0;//记录样品距离最近的中心
		for ( j=0;j<centernum;j++)//2
			if (tdistance>GetDistance(m_pattern[i],m_center[j],distype))
			{
				tdistance=GetDistance(m_pattern[i],m_center[j],distype);
				index=j;
			}

		if (tdistance>maxdistance/2)//样品到最近中的距离大于阈值,建立新的聚类中心
		{
				++centernum;
				for (int m=0;m<N*N;m++)
					m_center[centernum-1].feature[m]=m_pattern[i].feature[m];
				m_center[centernum-1].index=centernum;
				m_pattern[i].category=centernum;
		}
		else//归入index类中
		{
			m_pattern[i].category=m_center[index].index;
			CalCenter(&m_center[index]);
		}
			
	}
	delete []m_center;

}
/************************************************************
*函数名称		Zuiduanjulifa()
*参数			void
*返回值 		void
*函数功能		按照最短距离法对全体样品进行分类
************************************************************/
void CCluster::Zuiduanjulifa()//最短距离法
{
	GetFeature();

	double  T;//阈值
	int		distype;//距离的形式(欧氏、余弦。。。)
	int     i,j;

	double minous,maxous,mincos,maxcos,minbcos,maxbcos,mintan,maxtan;

	minous=MAX; mincos=MAX; minbcos=MAX; mintan=MAX;
	maxous=0; maxcos=0; maxbcos=0; maxtan=0;
	//计算四种距离模式的参考值
	for (  i=0;i<patternnum-1;i++)
		for ( j=i+1;j<patternnum;j++)
		{
			if (minous>GetDistance(m_pattern[i],m_pattern[j],1))
				minous=GetDistance(m_pattern[i],m_pattern[j],1);
			if (maxous<GetDistance(m_pattern[i],m_pattern[j],1))
				maxous=GetDistance(m_pattern[i],m_pattern[j],1);

			if (mincos>GetDistance(m_pattern[i],m_pattern[j],2))
				mincos=GetDistance(m_pattern[i],m_pattern[j],2);
			if (maxcos<GetDistance(m_pattern[i],m_pattern[j],2))
				maxcos=GetDistance(m_pattern[i],m_pattern[j],2);

			if (minbcos>GetDistance(m_pattern[i],m_pattern[j],3))
				minbcos=GetDistance(m_pattern[i],m_pattern[j],3);
			if (maxbcos<GetDistance(m_pattern[i],m_pattern[j],3))
				maxbcos=GetDistance(m_pattern[i],m_pattern[j],3);
			
			if (mintan>GetDistance(m_pattern[i],m_pattern[j],4))
				mintan=GetDistance(m_pattern[i],m_pattern[j],4);
			if (maxtan<GetDistance(m_pattern[i],m_pattern[j],4))
				maxtan=GetDistance(m_pattern[i],m_pattern[j],4);
		}
	DlgInfor mDlgInfor;
	mDlgInfor.ShowInfor(minous,maxous,mincos,maxcos,minbcos,maxbcos,mintan,maxtan);

	if (mDlgInfor.DoModal()==IDOK)
	{
		T=mDlgInfor.m_T;
		distype=mDlgInfor.m_DisType;
	}
	else return;

    //初始化,所有样品各分一类 
	centernum=patternnum;
	m_center=new Center[centernum];
	for ( i=0;i<patternnum;i++)
	{
		m_pattern[i].category=i+1;

		for (j=0;j<N*N;j++)
			m_center[i].feature[j]=m_pattern[i].feature[j];
		m_center[i].index=i+1;
	}

	while (1)
	{
		int pi,pj;
		double mindis;

		pi=0;
		pj=0;
		mindis=MAX;
		//寻找距离最近的两类pi、pj,记录最小距离mindis
		for ( i=0;i<patternnum-1;i++)
			for ( j=i+1;j<patternnum;j++)
				if (m_pattern[i].category!=m_pattern[j].category)
					if (GetDistance(m_pattern[i],m_pattern[j],distype)<mindis)
					{
						mindis=GetDistance(m_pattern[i],m_pattern[j],distype);
						pi=i;
						pj=j;
					};
		if (mindis<=T)//距离小于阈值,合并pi、pj类
		{
			if (pi>pj)//将较大类号归入较小类号
			{
				int temp=pi;
				pi=pj;
				pj=temp;
			}
			int tcenter=m_pattern[pj].category;
			for ( i=0;i<patternnum;i++)
			{
				if (m_pattern[i].category==tcenter)
					m_pattern[i].category=m_pattern[pi].category;
				if (m_pattern[i].category>tcenter)//保持序号的连续性
					m_pattern[i].category--;
			}
		}
		else break;//最小距离大于阈值,退出循环
	}
	delete []m_center;

}
/************************************************************
*函数名称		Zuichangjulifa()
*参数			void
*返回值		    void
*函数功能		按照最长距离法对全体样品进行分类
************************************************************/
void CCluster::Zuichangjulifa()//最长距离法
{
	GetFeature();

	double  T;//阈值
	int		distype;//距离的形式(欧氏、余弦。。。)
	int     i,j;

	double minous,maxous,mincos,maxcos,minbcos,maxbcos,mintan,maxtan;

	minous=MAX; mincos=MAX; minbcos=MAX; mintan=MAX;
	maxous=0; maxcos=0; maxbcos=0; maxtan=0;
	//计算四种距离模式的参考值
	for (  i=0;i<patternnum-1;i++)
		for ( j=i+1;j<patternnum;j++)
		{
			if (minous>GetDistance(m_pattern[i],m_pattern[j],1))
				minous=GetDistance(m_pattern[i],m_pattern[j],1);
			if (maxous<GetDistance(m_pattern[i],m_pattern[j],1))
				maxous=GetDistance(m_pattern[i],m_pattern[j],1);

			if (mincos>GetDistance(m_pattern[i],m_pattern[j],2))
				mincos=GetDistance(m_pattern[i],m_pattern[j],2);
			if (maxcos<GetDistance(m_pattern[i],m_pattern[j],2))
				maxcos=GetDistance(m_pattern[i],m_pattern[j],2);

			if (minbcos>GetDistance(m_pattern[i],m_pattern[j],3))
				minbcos=GetDistance(m_pattern[i],m_pattern[j],3);
			if (maxbcos<GetDistance(m_pattern[i],m_pattern[j],3))
				maxbcos=GetDistance(m_pattern[i],m_pattern[j],3);
			
			if (mintan>GetDistance(m_pattern[i],m_pattern[j],4))
				mintan=GetDistance(m_pattern[i],m_pattern[j],4);
			if (maxtan<GetDistance(m_pattern[i],m_pattern[j],4))
				maxtan=GetDistance(m_pattern[i],m_pattern[j],4);
		}
	DlgInfor mDlgInfor;
	mDlgInfor.ShowInfor(minous,maxous,mincos,maxcos,minbcos,maxbcos,mintan,maxtan);

	if (mDlgInfor.DoModal()==IDOK)
	{
		T=mDlgInfor.m_T;
		distype=mDlgInfor.m_DisType;
	}
	else return;

    //初始化,所有样品各归一类
	for ( i=0;i<patternnum;i++)
	{
		m_pattern[i].category=i+1;
	}
 
	centernum=patternnum;

	while (1)
	{
		int pi,pj;
		double mindis,maxdis;

		pi=0;
		pj=0;
		mindis=MAX;
        //求两类间的最大距离,找出所有类间距离中最小的为mindis,记录类号pi,pj
		for ( i=1;i<=centernum-1;i++)
			for ( j=i+1;j<=centernum;j++)
			{
   				maxdis=-1;
				for (int m=0;m<patternnum-1;m++)
					for (int n=m+1;n<patternnum;n++)
					{
						if ((m_pattern[m].category==i)&&(m_pattern[n].category==j)||((m_pattern[m].category==j)&&(m_pattern[n].category==i)))
							if (GetDistance(m_pattern[m],m_pattern[n],distype)>maxdis)
							{
								maxdis=GetDistance(m_pattern[m],m_pattern[n],distype);
							}
					}
				if ((maxdis<mindis)&&(maxdis!=-1))
				{
					mindis=maxdis;
					pi=i;
					pj=j;
				}
			}
		if (mindis<T)//距离小于阈值,合并pi、pj类
		{
			int tcenter=pj;
			for ( i=0;i<patternnum;i++)
			{
				if (m_pattern[i].category==tcenter)
					m_pattern[i].category=pi;
				if (m_pattern[i].category>tcenter)//对样品排序,保持类号的连续性
					m_pattern[i].category--;
			}
			centernum--;

⌨️ 快捷键说明

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