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

📄 cs2dlg.cpp

📁 完成BP人工神经网络算法的学习
💻 CPP
字号:
// cs2Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "cs2.h"
#include "cs2Dlg.h"
#include "math.h"
#include "InputStudyCount.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCs2Dlg dialog

CCs2Dlg::CCs2Dlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCs2Dlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCs2Dlg)
	m_maxerr = _T("");
	m_count = _T("");
	m_Learn = _T("");
	m_x1 = _T("");
	m_x2 = _T("");
	m_y1 = _T("");
	m_y2 = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCs2Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCs2Dlg)
	DDX_Text(pDX, ID_maxerr, m_maxerr);
	DDX_Text(pDX, IDC_count, m_count);
	DDX_Text(pDX, IDC_Learn, m_Learn);
	DDX_Text(pDX, IDC_EDIT5, m_x1);
	DDX_Text(pDX, IDC_EDIT6, m_x2);
	DDX_Text(pDX, IDC_EDIT7, m_y1);
	DDX_Text(pDX, IDC_EDIT8, m_y2);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCs2Dlg, CDialog)
	//{{AFX_MSG_MAP(CCs2Dlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON4, OnInputFished)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	ON_EN_CHANGE(IDC_EDIT5, OnChangeEdit5)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCs2Dlg message handlers

BOOL CCs2Dlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CCs2Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CCs2Dlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CCs2Dlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

static float w1[3][4],w2[4][4],w3[4][3],EMAX[200000];
static long count;


void CCs2Dlg::OnButton1() 
{
	LinkList L= (LinkList)malloc(sizeof(LNode));
	

	readexample(&L);
//	Print_L(&L);

//  initiarray(w1,w2,w3);         //随机初始权矩阵 
    initiarray2(w1,w2,w3);        //显示初始权矩阵
//	printarray(w1,w2,w3);

//	printf("---------------\n");
		
    learn(L, w1,w2,w3,EMAX);

 //  assess(w1,w2,w3);

  // See_emax(EMAX);

  // printarray(w1,w2,w3);


}

void CCs2Dlg::learn(LinkList L, float w1[][4],float w2[][4],float w3[][3],float EMAX[])
{
	int i,j,e;
	long t=1;
	unsigned long a=0,count=0;
	float MAX=1.0,err,Learn;
	float E[41],E2[4],E3[4],E4[3],o1[3],o2[4],o3[4],o4[3];	
	LinkList p;
	   CString   ss;

        UpdateData(TRUE); 
        err=atof(m_maxerr);
        Learn=atof(m_Learn);

		if(err>=1||err<0.000009)
		{
			MessageBox("请重新输入一个0.00001~1.00000之间的数!","允许最大误差输入有错!");
		//	UpdateData(TRUE); 
            err=atof(m_maxerr);
			return ;
		}


		if(Learn>=1||Learn<0.00001)
		{
			MessageBox("请重新输入一个0.00001~1.00000之间的数!","学习率输入有错!");
		//	UpdateData(TRUE); 
            Learn=atof(m_Learn);
			return ;
		}


	while(MAX>err)
	{
		e=1;
		p=L->next;		

		while(p)
		{
		    o1[1]=p->x1;
			o1[2]=p->x2;

			for(i=1;i<=3;i++)
				o2[i]=1/(1+exp(-(w1[1][i]*o1[1]+w1[2][i]*o1[2])));   //第2层输出

            for(i=1;i<=3;i++)
				o3[i]=1/(1+exp(-(w2[1][i]*o2[1]+w2[2][i]*o2[2]+w2[3][i]*o2[3])));    //第3层输出

			for(i=1;i<=2;i++)
				o4[i]=1/(1+exp(-(w3[1][i]*o3[1]+w3[2][i]*o3[2]+w3[3][i]*o3[3])));     //第4层输出				

			E4[1]=o4[1]-p->y1;           //计算每次输出误差
			E[e++]=fabs(E4[1]);          //存放每次误差
			
		    E4[2]=o4[2]-p->y2;
			E[e++]=fabs(E4[2]);

			for(i=1;i<=3;i++)
				E3[i]=o3[i]*(1-o3[i])*(w3[i][1]*E4[1]+w3[i][2]*E4[2]);     //第3层误差
			

            for(i=1;i<=3;i++)
				E2[i]=o2[i]*(1-o2[i])*(w2[i][1]*E3[1]+w2[i][2]*E3[2]+w2[i][3]*E3[3]);     //第2层误差
      

            for(i=1;i<=3;i++)   
				for(j=1;j<=2;j++)
					w3[i][j]=w3[i][j]-Learn*E4[j]*o3[i];                 //修改W3矩阵

			for(i=1;i<=3;i++)
				for(j=1;j<=3;j++)
					w2[i][j]=w2[i][j]-Learn*E3[j]*o2[i];                //修改W2矩阵

			for(i=1;i<=2;i++)
				for(j=1;j<=3;j++)
					w1[i][j]=w1[i][j]-Learn*E2[j]*o1[i];	            //修改W1矩阵

			p=p->next;

		}  //while(p)

        count++;                      // 学习遍数+1
	


		MAX=MAXE(E,e);                //计算最大误差

        EMAX[t++]=MAX;

		
	}//while(MAX>err) 

    ss.Format("%ld",count);
	SetDlgItemText(IDC_count,ss); 

		//printf("学习遍数count=%ld\n",count); 	


}




void CCs2Dlg::readexample(LinkList *L)                 //从指定文件读取实例
{
		FILE *fp;
		LinkList p=*L,r;

		if((fp=fopen("c:\\bp1.txt","r"))==NULL)
		{
		     MessageBox("请检查C盘对应bp1.txt文件!","打开文件出错!");
		     exit(0);
		}

		while(!feof(fp))
		{
			r=(LinkList)malloc(sizeof(LNode));
			r->next=NULL;
			p->next=r;
			fscanf(fp,"%f%f%f%f",&r->x1,&r->x2,&r->y1,&r->y2);

			p=r;
		}

		fclose(fp);
}


void CCs2Dlg::initiarray(float w1[][4],float w2[][4],float w3[][3])             //随机初始权矩阵 
{
	int i,j;
	for(i=1;i<=2;i++)
		for(j=1;j<=3;j++)
			w1[i][j]=rand()%100*1.0/100;

	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++)
			w2[i][j]=rand()%100*1.0/100;

	for(i=1;i<=3;i++)
		for(j=1;j<=2;j++)
			w3[i][j]=rand()%100*1.0/100;
}


void CCs2Dlg::initiarray2(float w1[][4],float w2[][4],float w3[][3])   //显示初始权矩阵
{
	FILE *fp;
	int i,j;
    
	if((fp=fopen("c:\\bp11.txt","r"))==NULL)
	{
		MessageBox("请检查C盘对应bp11.txt文件!","打开文件出错!");
		exit(0);
	}

	for(i=1;i<=2;i++)
		for(j=1;j<=3;j++)
			fscanf(fp,"%f",&w1[i][j]);

	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++)
			fscanf(fp,"%f",&w2[i][j]);

	for(i=1;i<=3;i++)
		for(j=1;j<=2;j++)
			fscanf(fp,"%f",&w3[i][j]);

		fclose(fp);
}



float CCs2Dlg::MAXE(float E[21],int e)              //返回最大误差值
{
	float max=0;
	int i;

	for(i=1;i<e;i++)
		if(max<E[i])
			max=E[i];

		return max;
}


/*
			
void CCs2Dlg::printarray(float w1[][4],float w2[][4],float w3[][3])       //输出权矩阵
{
    int i,j;

	printf("最后权矩阵如下:\n");

	for(i=1;i<=2;i++)
		for(j=1;j<=3;j++)
			printf("w1[%d][%d]=%f  ",i,j,w1[i][j]);
		printf("\n");

	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++)
				printf("w2[%d][%d]=%f  ",i,j,w2[i][j]);
			printf("\n");

	for(i=1;i<=3;i++)
		for(j=1;j<=2;j++)
				printf("w3[%d][%d]=%f  ",i,j,w3[i][j]);
			printf("\n");
}
*/

void CCs2Dlg::Print_L(LinkList *L)                 //输出读取的实例
{
	LinkList p=(*L)->next;

	if(!p)	
		MessageBox("链表创建为空!","链表信息");	        

	while(p)
	{
		printf("%f  %f  %f  %f\n",p->x1,p->x2,p->y1,p->y2);
		p=p->next;
	}
	printf("\n");
}

/*
void CCs2Dlg::See_emax(float EMAX[])
{
	long i;
	printf("输入学习的遍数:");
	scanf("%d",&i);	
	printf("EMAX[%ld]=%f \n",i,EMAX[i]);
}

*/
void CCs2Dlg::assess(float w1[][4],float w2[][4],float w3[][3])
{
	int i;
	float o1[3],o2[4],o3[4],o4[3],b[3],x2,x1,y1,y2;
	CString s1,s2,s3,s4;
	UpdateData(true);
	o1[1]=atof(m_x1);
	o1[2]=atof(m_x2);

	if(o1[1]>=1||o1[1]<0.00001)
		{
			MessageBox("请重新输入一个0~1之间的小数!","X1输入有错!");
		//	UpdateData(TRUE); 
            o1[1]=atof(m_x1);
			return ;
		}

		if(o1[2]>=1||o1[2]<0.00001)
		{
			MessageBox("请重新输入一个0~1之间的小数!","X2输入有错!");
		//	UpdateData(TRUE); 
            o1[2]=atof(m_x2);
			return ;
		}



//	printf("输入实例x1,x2:");
//	scanf("%f%f",&o1[1],&o1[2]);

    for(i=1;i<=3;i++)
		o2[i]=1/(1+exp(-(w1[1][i]*o1[1]+w1[2][i]*o1[2])));   //第2层输出

    for(i=1;i<=3;i++)
	    o3[i]=1/(1+exp(-(w2[1][i]*o2[1]+w2[2][i]*o2[2]+w2[3][i]*o2[3])));    //第3层输出

	for(i=1;i<=2;i++)
		o4[i]=1/(1+exp(-(w3[1][i]*o3[1]+w3[2][i]*o3[2]+w3[3][i]*o3[3])));     //第4层输出
	s1.Format("%f",o4[1]);
	s2.Format("%f",o4[2]);
    SetDlgItemText(IDC_EDIT7,s1);
	SetDlgItemText(IDC_EDIT8,s2);

		

//	printf("y1=%f,y2=%f\n",o4[1],o4[2]);

//	printf("对象X的评价:");

//	for(i=1;i<=2;i++)
//	{
		b[1]=(float)((int)(o4[1]*10+0.5))/10.0;

	    switch ((int)(10*b[1]))
		{
		case 10:  SetDlgItemText(IDC_EDIT9,"“肯定是”属于R1类");   break;
	 	 case 9 :  SetDlgItemText(IDC_EDIT9,"“几乎是”属于R1类");   break;
		 case 8 :  SetDlgItemText(IDC_EDIT9,"“极是”属于R1类");     break;
		 case 7 :  SetDlgItemText(IDC_EDIT9,"“很是”属于R1类");     break;
         case 6 : SetDlgItemText(IDC_EDIT9,"“相当是”属于R1类");   break;
         case 5 :  SetDlgItemText(IDC_EDIT9,"“差不多是”属于R1类"); break;
		 case 4 :  SetDlgItemText(IDC_EDIT9,"“比较像是”属于R1类"); break;
		 case 3 :  SetDlgItemText(IDC_EDIT9,"“有些像是”属于R1类"); break;
		 case 2 :  SetDlgItemText(IDC_EDIT9,"“有点像是”属于R1类"); break;
		 case 1 :  SetDlgItemText(IDC_EDIT9,"“稍稍像是”属于R1类"); break;
		 case 0 :  SetDlgItemText(IDC_EDIT9,"“肯定不是”属于R1类"); break;
		 default:  break;
		
	   }


		b[2]=(float)((int)(o4[2]*10+0.5))/10.0;

	    switch ((int)(10*b[2]))
		{
		case 10:  SetDlgItemText(IDC_EDIT10,"“肯定是”属于R2类");   break;
	 	 case 9 :  SetDlgItemText(IDC_EDIT10,"“几乎是”属于R2类");   break;
		 case 8 :  SetDlgItemText(IDC_EDIT10,"“极是”属于R2类");     break;
		 case 7 :  SetDlgItemText(IDC_EDIT10,"“很是”属于R2类");     break;
         case 6 : SetDlgItemText(IDC_EDIT10,"“相当是”属于R2类");   break;
         case 5 :  SetDlgItemText(IDC_EDIT10,"“差不多是”属于R2类"); break;
		 case 4 :  SetDlgItemText(IDC_EDIT10,"“比较像是”属于R2类"); break;
		 case 3 :  SetDlgItemText(IDC_EDIT10,"“有些像是”属于R2类"); break;
		 case 2 :  SetDlgItemText(IDC_EDIT10,"“有点像是”属于R2类"); break;
		 case 1 :  SetDlgItemText(IDC_EDIT10,"“稍稍像是”属于R2类"); break;
		 case 0 :  SetDlgItemText(IDC_EDIT10,"“肯定不是”属于R2类"); break;
		 default:  break;
		
	   }


//	   if(i==1)    SetDlgItemText(IDC_EDIT9,"");
///	   if(i==2)    SetDlgItemText(IDC_EDIT10,"属于R2类");
//	 }

//	printf("\n");
}

void CCs2Dlg::OnInputFished() 
{
     assess(w1,w2,w3);	
}

void CCs2Dlg::OnButton2() 
{
    CString output,s;
	output="\nw1矩阵:\n";
	int i,j;
    for(i=1;i<=2;i++)
	{
		for(j=1;j<=3;j++)
		{
		  s.Format("%f     ",w1[i][j]);
		  output=output+s;
		}
		output=output+"\n";
	}
	output=output+"\nw2矩阵:\n";
  

    for(i=1;i<=3;i++)
	{
		for(j=1;j<=3;j++)
		{
		  s.Format("%f     ",w2[i][j]);
		  output=output+s;
		}
		output=output+"\n";
	}
    output=output+"\nw3矩阵:\n";
			

    for(i=1;i<=3;i++)
	{
		for(j=1;j<=2;j++)
		{ 
		  s.Format("%f     ",w3[i][j]);
		  output=output+s;
		}
		output=output+"\n";
	}
	MessageBox(output,"显示连接权矩阵");
}

void CCs2Dlg::OnButton3() 
{
    
	InputStudyCount dlg;
	dlg.setValue(EMAX);
   	dlg.DoModal();
	
}

void CCs2Dlg::OnChangeEdit5() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	
}

⌨️ 快捷键说明

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