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

📄 dlg_location.cpp

📁 数据分析系统主要研究大量的数据
💻 CPP
字号:
// Dlg_location.cpp : implementation file
//

#include "stdafx.h"
#include "dataanalisis.h"
#include "Dlg_location.h"
#include "Dlg_common.h"
#include "MainFrm.h"
#include "math.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDlg_location dialog


CDlg_location::CDlg_location(CWnd* pParent /*=NULL*/)
	: CDialog(CDlg_location::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlg_location)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CDlg_location::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlg_location)
	DDX_Control(pDX, IDC_EDIT2, m_y);
	DDX_Control(pDX, IDC_EDIT1, m_x);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlg_location, CDialog)
	//{{AFX_MSG_MAP(CDlg_location)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlg_location message handlers////

const int N=100;//用户输入的数据对个数最大不能超过N
double x3[N],y3[N];//存储用户输入的自变量和因变量
double x[N],y[N];//存储预处理后的自变量和因变量的值
double px[N],py[N],yp[N];//存储排序后自变量、因变量的频率和与之对应的因变量
double ppx[N],ppy[N];//存储频率值
double DX=0,DY=0;//方差
double averagex,averagey;//平均数
double middata;//中位数
double minlicha,licha1,licha2,licha3,licha4;//定义离差变量
double k,b1;//线性模型y=k*x+b1的系数
double a,b,c;//二次曲线模型y=a*x^2+b*x+c的系数
double k1,a1;//指数模型y=k1*pow(a1,x)的系数
double k3,a3;//对数模型y=k3*log(a3,x)的系数

double yuchuli(double x0[],double y0[],int n);
double zhishu(double x[],double y[],int n);
double linexing(double x[],double y[],int n);
double erciquxian(double x[],double y[],int n);
double duishu(double x[],double y[],int n);
double licha();
double pinshu(double x3[],double y3[],int n);
double fangcha(double x3[],double y3[],int n);
double averagezhi(double x3[],double y3[],int n);
double zhongweishu(double x3[],double y3[],int n);
double input(int n);

void CDlg_location::OnOK() 
{
	// TODO: Add extra validation here
	extern int n;
	extern int g;
    char cEdit1[10],cEdit2[10];
    m_x.GetWindowText(cEdit1,10);
	m_y.GetWindowText(cEdit2,10);
	x3[g]=atof((LPCTSTR)cEdit1);
	y3[g]=atof((LPCTSTR)cEdit2);
	x[g]=x3[g];
	y[g]=y3[g];
	g++;
		
	if(g<n)
	{	   
		CDialog::OnOK();
		CDlg_location location;
		location.DoModal();
	}
	else
	{
       yuchuli(x3,y3,n);//调用数据预处理模块对数据进行处理
	   linexing(x,y,n);//调用线性模型
	   erciquxian(x,y,n);//调用二次曲线模型
	   zhishu(x,y,n);//调用指数模型
	   duishu(x,y,n);//调用对数模型
	   licha();
	   pinshu(x3,y3,n);
	   fangcha(x3,y3,n);
	   //averagezhi(x3,y3,n);
	   zhongweishu(x3,y3,n);  
	}
	CDialog::OnOK();
//	CDlg_common common;
//	common.DoModal();
	
}

//////////////////////////////////////////////////////////////////////
///数据预处理模块////

int mid;//修改时用来存储中间变量的值
double kuaixiugai(int low,int high);

double yuchuli(double x[],double y[],int n)
{
	int j;
	double sum=0;//一个累加器
	double a[N],b;//数组a[N]用来存储相邻数据的变化速率即斜率,b为其平均数
	for(int i=0;i<n;i++) //计算出相邻数据的斜率
		a[i]=(y[i+1]-y[i])/(x[i+1]-x[i]); 
   	for(i=0;i<n-1;i++) //计算总量
		sum+=fabs(a[i]); 
	b=sum/(n-1);//计算平均数

	/*处理单个和块异常数据*/
	for(i=0;i<n;i++)
	{
	     if(fabs(a[i])>b&&fabs(a[i-1])>b)//单个异常数据的检测
		 {
			x[i]=(x[i-1]+x[i+1])/2;
			y[i]=(y[i-1]+y[i+1])/2;
		 }
		 if(fabs(a[i])>b&&fabs(a[i+1])<b)//块异常数据的检测
		 {
			 for(j=i;j<n;j++)//查找块异常数据的末位置
			    j++;
		     j++;//对应在数组x[]和y[]中的位置
	    
	          kuaixiugai(i,j);//调用块修改递归算法
		 }
		
    }
	return x[N];
	return y[N];
}

double kuaixiugai(int low,int high)
{//利用递归算法实现的块修改功能模块
	int k0=-1;
	if(k0==-1)  k0=high;
	mid=(low+high)/2;
	if(low!=mid&&high<k0)
	{	
		x[mid]=(x[low]+x[high])/2;
     	y[mid]=(y[low]+y[high])/2;
		high=mid;
	    kuaixiugai(low,high);
    }
	if(high<k0)
	{
		low=high*2-low;
	    high=(high+1)*2-high;
		kuaixiugai(low,high);
	}
	return x[N];
	return y[N];
}
///////////////////////////////////////////////////////////////////////
////线性模型模块////

double linexing(double x[],double y[],int n)
{  
    /*…………………k和b分别是线形方程y=k*x+b的系数和截距,
	sum,sum1,sum2,sum3,sum4分别存储累加的和……………*/
	double sum=0,sum1=0,sum2=0,sum3=0,sum4=0;
	for(int i=0;i<n;i++)
	{
		sum1+=x[i];
        sum2+=x[i]*x[i];
		sum3+=y[i];
		sum4+=x[i]*y[i];
	}
	k=(double(sum3*sum1-sum4*n))/(sum1*sum1-sum2*n);//计算系数k
	b1=(double(sum4*sum1-sum3*sum2))/(sum1*sum1-sum2*n);//计算截距b

	/////计算离差////
	for(i=0;i<n;i++)
		sum+=fabs(y[i]-(k*x[i]+b1));
	licha1=sum/n;

    return k;
	return b1;
}
////////////////////////////////////////////////////////////////////////
////二次曲线模型模块////

double erciquxian(double x[],double y[],int n)
{
	double D;//一个变量作为分母
	double sum=0,sum1=0,sum2=0,sum3=0,sum4=0,sum5=0,sum6=0,sum7=0;//定义一些累加器
	for(int i=0;i<n;i++)
		{
			sum1+=x[i];
			sum2+=x[i]*x[i];
			sum3+=x[i]*x[i]*x[i];
			sum4+=x[i]*x[i]*x[i]*x[i];
			sum5+=y[i];
			sum6+=y[i]*x[i];
			sum7+=y[i]*x[i]*x[i];
		}
	D=((sum4*sum2-sum3*sum3)*(sum2*sum1-sum3*n)-(sum4*sum1-sum2*sum3)*(sum2*sum2-sum1*sum3));

	a=((sum7*sum2-sum6*sum3)*(sum2*sum1-sum3*n)-(sum7*sum1-sum5*sum3)*(sum2*sum2-sum1*sum3))/D;//计算系数a
	c=((sum7*sum2-sum6*sum3)*(sum4*sum1-sum2*sum3)-(sum7*sum1-sum5*sum3)*(sum4*sum2-sum3*sum3))/D;//计算系数c
	b=(sum7-a*sum4-c*sum2)/sum3;//计算系数b

    /////计算离差/////
	for(i=0;i<n;i++)
		sum+=fabs(y[i]-(a*x[i]*x[i]+b*x[i]+c));
	licha2=sum/n;

    return a;
	return b;
	return c;
} 

///////////////////////////////////////////////////////////////////////
////指数模型模块////

double zhishu(double x[],double y[],int n)
{
	double Y[N];
	double k2,a2,sum=0,sum1=0,sum2=0,sum3=0,sum4=0;
	double c[N];
	for(int i=0;i<n;i++)
	{
		c[i]=x[i];
		x[i]=y[i];
		y[i]=c[i];
	}

	for(i=0;i<n;i++)	
	{
		if(y[i]>0)
			Y[i]=log(y[i]);
	}
	for(i=0;i<n;i++)
	{
			if(Y[i]>0)//判断y值是否大于0,否则就不适合指数模型
			{
				for(i=0;i<n;i++)
				{
					sum1+=x[i];
					sum2+=x[i]*x[i];
					sum3+=y[i];
					sum4+=x[i]*y[i];
				}
				a2=(double(sum3*sum1-sum4*n))/(sum1*sum1-sum2*n);
				k2=(double(sum4*sum1-sum3*sum2))/(sum1*sum1-sum2*n);
				a1=exp(a2);
				k1=exp(k2);
			}
			else
				return 0;
	}

    ////计算离差////
	for(i=0;i<n;i++)
		sum+=fabs(y[i]-(k1*pow(a1,x[i])));
	licha3=sum/n;

	return k1;
	return a1;
}
	
///////////////////////////////////////////////////////////////////////
////对数模型模块////

double duishu(double X[],double Y[],int n)
{
    double c[N],sum=0;
	for(int i=0;i<n;i++)
	{//交换x和y的位置,来调用指数模型的功能模块
		c[i]=X[i];
		X[i]=Y[i];
		Y[i]=c[i];
	}
	zhishu(X,Y,n);//调用指数模型模块
	k3=k1;
	a3=a1;

	////计算离差////
	for(i=0;i<n;i++)
		sum+=fabs(y[i]-(k3*pow(a3,x[i])));
	licha4=sum/n;

	return k3;
	return a3;
}
////////////////////////////////////////////////////////////////////////
////比较离差////

double licha()
{
	minlicha=licha1;
	if(minlicha>licha2)
		minlicha=licha2;
	if(minlicha>licha3)
		minlicha=licha3;
	if(minlicha>licha4)
		minlicha=licha4;
	
	return minlicha;
}

////////////////////////////////////////////////////////////////////////
////统计频率功能模块程序////

double pinshu(double x3[],double y3[],int n)
{
	for(int i=0;i<n;i++)
	{
		ppx[i]=1;
		ppy[i]=1;
   	}
	for(i=0;i<n;i++)
	   for(int j=0;j<n;j++)
	   {
		    if(j==i);
			else
			{
				if(x3[i]==x3[j])//统计x[]中每个数据出现的次数
				  ppx[i]++;
				if(y3[i]==y3[j])//统计y[]中每个数据出现的次数
				  ppy[i]++; 
			}
	   }
	for(i=0;i<n;i++)
	{
	    ppx[i]=double(ppx[i])/n;//计算x中每个数据出现的频率
	    ppy[i]=double(ppy[i])/n;//计算y中每个数据出现的频率
	
	}
    for(i=0;i<n;i++)//排序因变量数据出现的频率,取频率前5个大值
	{
		for(int j=1;j<n;j++)
			if(ppy[i]<ppy[j])
			{
				py[i]=ppy[j];
				yp[i]=y3[j];
			}
	}
	return ppy[N];
	return yp[N];
	return py[N];
}

/////////////////////////////////////////////////////////////////
/////计算方差/////

double fangcha(double x3[],double y3[],int n)
{
	double EX=0,EY=0;
	//pinshu(x3,y3,n);//调用统计频数功能函数
	averagezhi(x3,y3,n);

	for(int i=0;i<n;i++)
	{
	    EX+=ppx[i]*x3[i];//计算x的数学期望
		EY+=ppy[i]*y3[i];//计算y的数学期望
	}
	for(int j=0;j<n;j++)
	{
	    DX+=(EX-averagex)* (EX-averagex);//计算x的方差
		DY+=(EY-averagey)* (EY-averagey); //计算x的方差
	}

	return DX;
	return DY;
} 

//////////////////////////////////////////////////////////////////
////计算均值程序模块////

double averagezhi(double x3[],double y3[],int n)
{  
    double sumx=0,sumy=0;
	for(int i=0;i<n;i++)
    {
        sumx+=x3[i];//计算x[]的总数
        sumy+=y3[i];//计算y[]的总数
     } 
    averagex=sumx/n; //计算x[]的平均数
    averagey=sumy/n; //计算x[]的平均数

	return averagex;
	return averagey;
}

///////////////////////////////////////////////////////////////////
//////计算中位数////////////

double zhongweishu(double x3[],double y3[],int n)
{
	double temp,y4[N];
	for(int i=0;i<n;i++)
		y4[i]=y3[i];

	for(i=0;i<n;i++)//对y的数据进行排序,以便找出它们的中位数
		for(int j=0;j<n-i-1;j++)
		{
			if(y4[j]>y4[j+1])//冒泡排序,从小到大
			{
				temp=y4[j];
				y4[j]=y4[j+1];
				y4[j+1]=temp;
			}
		}
	if(n%2==1)
		middata=y4[n/2];
	else
		middata=y4[n/2-1];

	return middata;
}


///////////////////////////////////////////////////////////////////

void CDlg_location::OnCancel() 
{
	// TODO: Add extra cleanup here
	
	CDialog::OnCancel();
}

⌨️ 快捷键说明

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