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

📄 studypage.cpp

📁 bp神经网络应用程序
💻 CPP
字号:
// StudyPage.cpp : implementation file
//

#include "stdafx.h"
#include "智能岩土工程.h"
#include "StudyPage.h"
#include "BPSheet.h"
#include "time.h"
#include "math.h"
#include "LookWnd.h"

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

/////////////////////////////////////////////////////////////////////////////
// CStudyPage property page

IMPLEMENT_DYNCREATE(CStudyPage, CPropertyPage)

CStudyPage::CStudyPage() : CPropertyPage(CStudyPage::IDD)
{
	//{{AFX_DATA_INIT(CStudyPage)
	m_ERROR = 0.0;
	m_NUM = 0;
	m = 0;mm = 0;
	n = 0;nn = 0;
	p = 0;pp = 0;
	q = 0;qq = 0;
	//}}AFX_DATA_INIT	
	W = NULL;
	V = NULL;
	D = NULL;
	E = NULL;
	Result = NULL;
	A = NULL;
	Y = NULL;
	S = NULL;
	B = NULL;
	L = NULL;
	C = NULL;
	Q = NULL;
	R = NULL;
	Error = NULL;
	USE = NULL;
}

CStudyPage::~CStudyPage()
{
	Delete(m, n, p, q);
}

void CStudyPage::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CStudyPage)
	DDX_Control(pDX, IDC_PROGRESS, m_Progress);
	DDX_Control(pDX, IDC_LIST2, m_ResultList2);
	DDX_Control(pDX, IDC_LIST, m_ResultList);
	DDX_Text(pDX, IDC_ERROR, m_ERROR);
	DDX_Text(pDX, IDC_NUMBER, m_NUM);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CStudyPage, CPropertyPage)
	//{{AFX_MSG_MAP(CStudyPage)
	ON_BN_CLICKED(IDC_STUDY, OnStudy)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStudyPage message handlers

void CStudyPage::OnStudy()
{
	// TODO: Add your control notification handler code here
//	Delete(m, n, p, q);
	InitialData();
	if(m==0)
		MessageBox("请输入样本!");
	else
	{
		InitialWVRQ();
		Study();
		ShowStudyResult();//显示连接权和阀值
		CountSampleTrueResult();
		ShowStudyResult2();//显示样本的实际输出
		UpdateData(FALSE);
		m_Progress.SetPos(num);
	}
	m_Progress.SetPos(0);
}

void CStudyPage::InitialData()
{
//删除上一次的原有记录
/*	int max = n>p?(n+1):(p+1);
	if(m_ResultList2.GetItemCount()!=0)
		m_ResultList2.DeleteAllItems();
	for(int ii=n+q; ii>=0; ii--)
		m_ResultList2.DeleteColumn(ii);
	if(m_ResultList.GetItemCount()!=0)
		m_ResultList.DeleteAllItems();
	for(ii=max; ii>=0; ii--)
		m_ResultList.DeleteColumn(ii);*/
//重新读取格式
	CBPSheet* MyBPSheet;
	MyBPSheet = (CBPSheet*)this->GetParent();
//网络模型:m个模式对 n个输入层 p个中间层 q个输出层
	n = MyBPSheet->m_Sample.n;
//	n = MyBPSheet->m_Modle.m_InputNum;
	p = MyBPSheet->m_Sample.p;
//	p = MyBPSheet->m_Modle.m_MidNum;
	q = MyBPSheet->m_Sample.q;
//	q = MyBPSheet->m_Modle.m_OutputNum;
//样本数据:在样本类里实现 借过来用用
	m = MyBPSheet->m_Sample.m;
//学习系数
	a = MyBPSheet->m_Parameter.m_A; 
	b = MyBPSheet->m_Parameter.m_B;
//全局误差
	error = MyBPSheet->m_Parameter.m_Error;
//预设训练次数
	num = MyBPSheet->m_Parameter.m_NUM;
//进度
	m_Progress.SetRange(0,num);
	m_Progress.SetStep(1);
	m_Progress.SetPos(0);
////////////////////////////////////////////////////////////////////////////////
//分配空间
////////////////////////////////////////////////////////////////////////////////
	Error = new double[m];
	USE = new int[m];
	for(int ii=0; ii<m; ii++)
	{
		USE[ii] = 0;
		Error[ii] = 0.0000;
	}
	A = new double[n];
	Y = new double[q];
//	double *S;S[p]
	S = new double[p];
//	double *B;B[p]
	B = new double[p];
//	double *L;L[q]
	L = new double[q];
//	double *C;C[q]
	C = new double[q];
//  double **D;D[m][q]
	D = new double *[m];
	for (int i=0; i<m; i++)
	{
		D[i] = new double[q];
	}
//  double **E;E[m][p]
	E = new double *[m];
	for (i=0; i<m; i++)
	{
		E[i] = new double[p];
	}
//	double **W;W[p][n] 连接权W
	W = new double *[p];
	for (ii=0; ii<p; ii++)
	{
		W[ii] = new double[n];
	}
//	double **V;V[q][p] 连接权V
	V = new double *[q];
	for (ii=0; ii<q; ii++)
	{
		V[ii] = new double[p];
	}
//	double *Q;Q[p] 阀值Q
	Q = new double[p];
//	double *R;R[q] 阀值R
	R = new double[q];
//实际输出变量
	Result = new double *[m];
	for (ii=0; ii<m; ii++)
	{
		Result[ii] = new double[q];
	}
}
//学习所得的连接权和阀值
void CStudyPage::ShowStudyResult()
{
	int max = n>p?(n+1):(p+1);
	if(m_ResultList.GetItemCount()!=0)
		m_ResultList.DeleteAllItems();
	for(int ii=max; ii>=0; ii--)
		m_ResultList.DeleteColumn(ii);
	LV_COLUMN lvColumn;
	lvColumn.mask = LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH;
	lvColumn.fmt = LVCFMT_LEFT;
	lvColumn.cx = 100;
	for(ii=0; ii<=max; ii++)
	{
		if(ii==0)
		{
			lvColumn.iSubItem = ii;
			lvColumn.pszText = "单元"; 
			m_ResultList.InsertColumn(0,&lvColumn);
		}
		else
		{
			if(ii==max)
			{
				lvColumn.iSubItem = ii;
				m_ResultList.InsertColumn(ii,"阀值",LVCFMT_LEFT,100);
			}
			else
			{
				lvColumn.iSubItem = ii;
				CString str;
				str.Format("%d",ii);
				m_ResultList.InsertColumn(ii,str,LVCFMT_LEFT,100);
			}
		}
	}
	LV_ITEM lvItem;
	lvItem.mask = LVIF_TEXT;
	lvItem.iSubItem = 0;
//中间层的权系数和阀值
	CString strData;
	for(ii=0; ii<p; ii++)
	{
		CString str;
		CString str0 = "中间层单元:";
		str.Format("%d",ii+1);
		str=str0+str;
		m_ResultList.InsertItem(ii,str);
		for(int jj=0; jj<=n; jj++) //各单元的连接权和阀值 
		{
			if(jj==n)
			{
				strData.Format("%1.6f",Q[ii]);
				m_ResultList.SetItemText(ii,max,strData);
			}
			else
			{
				strData.Format("%1.6f",W[ii][jj]);
				m_ResultList.SetItemText(ii,jj+1,strData);
			}
		};
	}
//输出层的权系数和阀值
	for(ii=0; ii<q; ii++)
	{
		CString str;
		CString str0 = "输出层单元:";
		str.Format("%d",ii+1);
		str=str0+str;
		m_ResultList.InsertItem(ii,str);
		for(int jj=0; jj<=p; jj++)
		{
			if(jj==p)
			{
				strData.Format("%1.6f",R[ii]);
				m_ResultList.SetItemText(ii,max,strData);
			}
			else
			{
				strData.Format("%1.6f",V[ii][jj]);
				m_ResultList.SetItemText(ii,jj+1,strData);
			}
		};
	}
}

void CStudyPage::Study()
{
	FILE* InExcel = fopen("d:\\Report.xls", "w");
	m_NUM = 0;
	while(1)
	{
		for(int ii=0; ii<m; ii++)
		{
			/*{
			for(int ii=0; ii<p; ii++)
				for(int jj=0; jj<n; jj++)
					fprintf(InExcel, "%f	", W[ii][jj]);
			for(ii=0; ii<q; ii++)
				for(int jj=0; jj<p; jj++)
					fprintf(InExcel, "%f	", V[ii][jj]);
			fprintf(InExcel, "%f\n", 0.00001);
			}*/
			tmpSampleNum = SelectSampleData();
			GetS();
			GetB();
			GetL();
			GetC();
			GetD(tmpSampleNum);
			GetE(tmpSampleNum);
			GetWQ(tmpSampleNum);
			GetVR(tmpSampleNum);
			if(ii==m-1)
			{
				for(int jj=0; jj<m; jj++)
					USE[jj] = 0;
			}
		}
		m_NUM++;
		m_Progress.SetPos(m_NUM);
		if(IsStop())
			break;
	}
	fclose(InExcel);
}

double CStudyPage::BaseFUN(double x)
{
	x=0-x;
	return 1/(exp(x)+1);
}

void CStudyPage::GetS()
{
	double SUM = 0.0000;
	for(int ii=0; ii<p; ii++)
	{
		SUM = 0.0000;
		for(int jj=0; jj<n; jj++)
		{
			SUM+= W[ii][jj]*A[jj];
		}
		SUM = SUM-Q[ii];
		S[ii] = SUM;
	}
}

void CStudyPage::GetB()
{
	for(int ii=0; ii<p; ii++)
		B[ii] = BaseFUN(S[ii]);
}

void CStudyPage::GetL()
{
	double SUM=0.0000;
	for(int ii=0; ii<q; ii++)
	{
		SUM=0.0000;
		for(int jj=0; jj<p; jj++)
		{
			SUM+=V[ii][jj]*B[jj];
		}
		SUM = SUM-R[ii];
		L[ii] = SUM;
	}
}

void CStudyPage::GetC()
{
	for(int ii=0; ii<q; ii++)
	{
		C[ii] = BaseFUN(L[ii]);
	}
}

void CStudyPage::GetD(int sampleNum)
{
	double SUM = 0.0000;
	for(int ii=0; ii<q; ii++)
	{
		SUM+= (Y[ii]-C[ii])*(Y[ii]-C[ii]);
		D[sampleNum][ii] = (Y[ii]-C[ii])*C[ii]*(1-C[ii]);
	}
	Error[sampleNum] = SUM/2;
}

void CStudyPage::GetE(int sampleNum)
{
	double SUM = 0.0000;
	for(int ii=0; ii<p; ii++)
	{
		SUM = 0.0000;
		for(int jj=0; jj<q; jj++)
		{
			SUM+= D[sampleNum][jj]*V[jj][ii];
		}
		E[sampleNum][ii] = SUM*B[ii]*(1-B[ii]);
	}
}

void CStudyPage::GetVR(int sampleNum)
{
	for(int ii=0; ii<q; ii++)
	{
		for(int jj=0; jj<p; jj++)
			V[ii][jj] = V[ii][jj]+a*D[sampleNum][ii]*B[jj];
		R[ii] = R[ii] + a*D[sampleNum][ii];
	}

/*	for(int ii=0; ii<p; ii++)
	{
		for(int jj=0; jj<q; jj++)
		{
			V[jj][ii] = V[jj][ii]+a*D[sampleNum][jj]*B[ii];
		}
		R[ii] = R[ii] + a*D[sampleNum][ii];
	}*/
}

void CStudyPage::GetWQ(int sampleNum)
{
	for(int ii=0; ii<p; ii++)
	{
		for(int jj=0; jj<n; jj++)
			W[ii][jj] = W[ii][jj]+b*E[sampleNum][ii]*A[jj];
		Q[ii] = Q[ii] + b*E[sampleNum][ii];
	}

/*	for(int ii=0; ii<n; ii++)
	{
		for(int jj=0; jj<p; jj++)
		{
			W[jj][ii] = W[jj][ii]+b*E[sampleNum][jj]*A[ii];
		}
		Q[ii] = Q[ii] + b*E[sampleNum][ii];
	}*/
}

BOOL CStudyPage::IsStop()
{
	double SUM = 0.0000;
	for(int ii=0; ii<m; ii++)
		SUM+= Error[ii];
	m_ERROR = SUM;
	if(m_ERROR<=error||m_NUM>=num)
		return TRUE;
	return FALSE;
}

int CStudyPage::SelectSampleData()
{
	CBPSheet* MyBPSheet;
	MyBPSheet = (CBPSheet*)this->GetParent();	
	time_t tCurrent_time;
	srand((unsigned)time(&tCurrent_time));
	do
	{
		tmpSampleNum = (int)((rand()/(double)RAND_MAX)*m);
	}
	while(USE[tmpSampleNum]==1);
	USE[tmpSampleNum] = 1;
	for(int ii=0; ii<n; ii++)
		A[ii] = MyBPSheet->m_Sample.SampleData[tmpSampleNum][ii];
	for(ii=n; ii<n+q; ii++)
		Y[ii-n] = MyBPSheet->m_Sample.SampleData[tmpSampleNum][ii];
	return tmpSampleNum;
}

//显示学习所得的实际输出值
void CStudyPage::ShowStudyResult2()
{
	if(m_ResultList2.GetItemCount()!=0)
		m_ResultList2.DeleteAllItems();
	for(int ii=n+q; ii>=0; ii--)
		m_ResultList2.DeleteColumn(ii);
	CBPSheet* MyBPSheet;
	MyBPSheet = (CBPSheet*)this->GetParent();
	LV_COLUMN lvColumn;
	lvColumn.mask = LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH;
	lvColumn.fmt = LVCFMT_LEFT;
	lvColumn.cx = 100;
	for( ii=0; ii<=n+q; ii++)
	{
		if(ii==0)
		{
			lvColumn.iSubItem = ii;
			lvColumn.pszText = "样本";
			m_ResultList2.InsertColumn(0,&lvColumn);
		}
		else
		{
			if(ii<=n)
			{
				lvColumn.iSubItem = ii;
				lvColumn.pszText = "输入分量";
				m_ResultList2.InsertColumn(ii,&lvColumn);
			}
			else
			{
				lvColumn.iSubItem = ii;
				lvColumn.pszText = "实际输出分量";
				m_ResultList2.InsertColumn(ii,&lvColumn);
			}
		}
	}
	LV_ITEM lvItem;
	lvItem.mask = LVIF_TEXT;
	lvItem.iSubItem = 0;
	for(ii=0; ii<m; ii++)
	{
		lvItem.iItem = ii;
		CString str;
		str.Format("%d", ii+1);
		m_ResultList2.InsertItem(ii,str);
		for(int jj=1; jj<=n; jj++)
		{
			CString strData;
			strData.Format("%f", MyBPSheet->m_Sample.SampleData[ii][jj-1]);
			m_ResultList2.SetItemText(ii,jj,strData);
		};
		for(jj=n+1; jj<=n+q; jj++)
		{
			CString strData;
			strData.Format("%f", Result[ii][jj-n-1]);
			m_ResultList2.SetItemText(ii,jj,strData);
		}
	}
}

void CStudyPage::CountSampleTrueResult()
{
	CBPSheet* MyBPSheet;
	MyBPSheet = (CBPSheet*)this->GetParent();	
	for(int ii=0; ii<m; ii++)
	{
		for(int jj=0; jj<n; jj++)
			A[jj] = MyBPSheet->m_Sample.SampleData[ii][jj];
		GetS();
		GetB();
		GetL();
		GetC();
		for(jj=0; jj<q; jj++)
			Result[ii][jj] = C[jj];
		
	}
}

void CStudyPage::InitialWVRQ()
{
//连接权W
	time_t tCurrent_time;
	srand((unsigned)time(&tCurrent_time));
	for(int ii=0; ii<p; ii++)
		for(int jj=0; jj<n; jj++)
			W[ii][jj]= (2*rand()/(double)RAND_MAX-1);
//连接权V
	srand((unsigned)time(&tCurrent_time));
	for(ii=0; ii<q; ii++)
		for(int jj=0; jj<p; jj++)
			V[ii][jj]= (2*rand()/(double)RAND_MAX-1);
//阀值Q
	srand((unsigned)time(&tCurrent_time));
	for(ii=0; ii<p; ii++)
		Q[ii]= (2*rand()/(double)RAND_MAX-1);
//阀值R
	srand((unsigned)time(&tCurrent_time));
	for(ii=0; ii<q; ii++)
		R[ii]= (2*rand()/(double)RAND_MAX-1);
}

void CStudyPage::Delete(int m, int n, int p, int q)
{
//W
	if (W!= NULL)
	{		
		for (int ii=0; ii<p; ii++)
		{
			delete []W[ii];
			W[ii] = NULL;
		}
		delete []W;
		W = NULL;
	}
//V
	if (V!= NULL)
	{		
		for (int ii=0; ii<q; ii++)
		{
			delete []V[ii];
			V[ii] = NULL;
		}
		delete []V;
		V = NULL;
	}
//D
	if (D!= NULL)
	{		
		for (int ii=0; ii<p; ii++)
		{
			delete []D[ii];
			D[ii] = NULL;
		}
		delete []D;
		D = NULL;
	}
//E
	if (E!= NULL)
	{		
		for (int ii=0; ii<q; ii++)
		{
			delete []E[ii];
			E[ii] = NULL;
		}
		delete []E;
		E = NULL;
	}
//Reualt
	if (Result!= NULL)
	{		
		for (int ii=0; ii<q; ii++)
		{
			delete []Result[ii];
			Result[ii] = NULL;
		}
		delete []Result;
		Result = NULL;
	}
	if(A!=NULL)
	{
		delete []A;
		A = NULL;
	}
	if(Y!=NULL)
	{
		delete []Y;
		Y = NULL;
	}
	if(S!=NULL)
	{
		delete []S;
		S = NULL;
	}
	if(B!=NULL)
	{
		delete []B;
		B = NULL;
	}
	if(L!=NULL)
	{
		delete []L;
		L = NULL;
	}
	if(C!=NULL)
	{
		delete []C;
		C = NULL;
	}
	if(Q!=NULL)
	{
		delete []Q;
		Q = NULL;
	}
	if(R!=NULL)
	{
		delete []R;
		R = NULL;
	}
	if(Error!=NULL)
	{
		delete []Error;
		Error = NULL;
	}
	if(USE!=NULL)
	{
		delete []USE;
		USE = NULL;
	}
}

⌨️ 快捷键说明

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