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

📄 fisher1.cpp

📁 模式识别的经典算法FISHER算法,课程设计的实验作品
💻 CPP
字号:
#include<iostream.h>
#include<math.h>
#define N 4
///////////////////////////求样本的均值/////////////////
void average(double X[][N],double M[N],int k)  //求出mi向量
{
	for( int j=0;j<N;j++)
	{	  
		double sum=0; 
		for(int i=0;i<k;i++)
			sum=sum+X[i][j];
        M[j]=sum/k;
	} 
}
//////////////////////////////减去均值/////////////////////////
void Jian(double X[][N],double M[N],double Y[][N],int k)  //求出 (X-mi)向量
{
   for(int i=0;i<k;i++)
	   for(int j=0;j<N;j++)
		   Y[i][j]=X[i][j]-M[j];


}
///////////////////////////求类的离散度///////////////////////////////
void Lisan(double Sw1[N][N],double Y[][4],int k)   //求出S1、S2
{
    
	
	for(int i=0;i<k;i++)
		{
		    for(int r=0;r<N;r++)
				for(int s=0;s<N;s++)
				{ double	sum=Y[i][r]*Y[i][s];
				Sw1[r][s]=sum+Sw1[r][s];
				}
		}
			
}
/////////////////////////实现判别属于哪个类/////////////////////////
void Select(double *W,double *a)  //求出W向量
{
   double p=0;
   for(int i=0;i<N;i++)
	   p=p+W[i]*a[i];
   if(p>0) cout<<"经判定属于油层。"<<endl;
   else cout<<"经判定属于水层。"<<endl;


}
//////////////////////////矩阵求逆////////////////////////////////
int matinv1(double a[][N],int n)
{
	int i,j,k,i0;
	double ep=1e-12,w,z,cc;
	int p[N];
	double av[N][N];
	
	
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			av[i-1][j-1]=0;
	for(i=1;i<=n;i++)
		av[i-1][i-1]=1;


	for(k=1;k<=n;k++){
		w=0;
		for(i=k;i<=n;i++)
			if(fabs(a[i-1][k-1]) > fabs(w)){
					w=a[i-1][k-1];
					i0=i;
					}

		if(fabs(w)<ep)
			return 0;
		if(i0!=k)
			for(j=1;j<=n;j++){
				z=a[i0-1][j-1];
				a[i0-1][j-1]=a[k-1][j-1];
				a[k-1][j-1]=z;

				z=av[i0-1][j-1];
				av[i0-1][j-1]=av[k-1][j-1];
				av[k-1][j-1]=z;
				}



		p[k-1]=i0;
		for(j=1;j<=n;j++){
			a[k-1][j-1]=a[k-1][j-1]/w;
			av[k-1][j-1]=av[k-1][j-1]/w;
		}


		for(i=1;i<=n;i++)
			if(i!=k){
				cc=a[i-1][k-1];
				for(j=1;j<=n;j++){
					a[i-1][j-1]=a[i-1][j-1] - cc*a[k-1][j-1];
					av[i-1][j-1]=av[i-1][j-1] - cc*av[k-1][j-1];
				}
			}

	}

    for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			a[i-1][j-1]=av[i-1][j-1];
    return 1;
}
//////////////////测试数据//////////////////////////////////////////////
void ceshi(double W[],double Z[][N],int k)
{
   
   for(int i=0;i<k;i++){
	   double p=0;
	   for(int j=0;j<N;j++)
	   	      p=p+Z[i][j]*W[j];
   if(p>0) cout<<i<<"经判定属于油层。"<<endl;
   else cout<<i<<"经判定属于水层。"<<endl;
   }
	  
}
////////////////////////////////////////////////////
void main()
{
	double X1[10][N]={0.276,0.18,0.446,0.683,
		0.378,0.2,0.764,0.673,
		0.325,0.2,0.8,0.633,
		0.138,0.21,0.75,0.728,
		0.29,0.241,0.87,0.649,
		0.27,0.19,1.73,0.631,
		0.45,0.23,2.66,0.544,
		0.076,0.26,0.85,0.733,
		0.346,0.27,1.32,0.621,
		0.186,0.3,0.56,0.796};
    double X2[9][N]={0.62,0.24,6.22,0.544,
		0.61,0.25,1.42,0.494,
		0.62,0.27,1.46,0.51,
		0.56,0.13,1.3,0.372,
		0.56,0.2,3.0,0.221,
		0.29,0.25,4.66,0.395,
		0.302,0.22,3.18,0.25,
		0.347,0.19,17.9,0.23,
		0.269,0.25,8.7,0.145};
	double M1[N],M2[N];
	average(X1,M1,10);//////求均值
	average(X2,M2,9);
	double Y1[10][N],Y2[9][N];
	Jian(X1,M1,Y1,10);/////////减去均值	
	Jian(X2,M2,Y2,9);
	double Sw1[N][N],Sw2[N][N],Sw[N][N];
	for(int r=0;r<N;r++)///////矩阵赋初值
		for(int s=0;s<N;s++)
		{
			Sw1[r][s]=0;
			Sw2[r][s]=0;
			
		}

	Lisan(Sw1,Y1,10);///////求离散度矩阵
	Lisan(Sw2,Y2,9);
	for(r=0;r<N;r++)
		for(int s=0;s<N;s++)
			Sw[r][s]=Sw1[r][s]+Sw2[r][s];//////类内离散度矩阵
	
   matinv1(Sw,N);/////矩阵求逆
   double W[N];
   for(r=0;r<N;r++)
   {double sum=0;
	   for(int s=0;s<N;s++)
	   {
	       sum=sum+(M1[s]-M2[s])*Sw[r][s];//////求最优解
	   }
	   W[r]=sum;
   }

   	for(int i=0;i<N;i++)
		cout<<W[i]<<"   ";
	cout<<endl;
		  
    double Z[5][N]={0.302,0.23,1.78,0.59,
		0.344,0.24,3.4,0.618,
		0.358,0.21,1.37,0.619,
		0.432,0.215,0.9,0.214,
		0.47,0.2,2.9,0.22};
	ceshi(W,Z,5);

///////////////////////////////////////////////////
	cout<<"请输入要判别的数据:"<<endl;
	double a[N];
	for(i=0;i<N;i++)
		cin>>a[i];
	
	Select(W,a);
}

⌨️ 快捷键说明

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