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

📄 dlghop.cpp

📁 人工神经网络基本模型:BP、ART、Hopfield、SOM
💻 CPP
字号:
// DlgHop.cpp : implementation file
//

#include "stdafx.h"
#include "ANN.h"
#include "DlgHop.h"

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

	const	int			PANES_Row=11;
	const	int			PANES_Col=9;
	const	int			PANE_Height=12;
	const	int			PANE_Width=12;
	const	COLORREF	PANES_BkColor=RGB(255,255,255);//RGB(0xd4,0xd0,0xc8);
	const	COLORREF	PANES_BorderColor=RGB(0x0,0x4d,0x99);
	const	COLORREF	PANE_FillColor=RGB(0,125,0);//RGB(0,0,0);
	const	COLORREF	PANE_NullColor=PANES_BkColor;//RGB(255,255,0);

	const	int			PANES_x10=20;
	const	int			PANES_y10=20;
	const	int			PANES_x11=PANES_x10+PANE_Width*PANES_Col;
	const	int			PANES_y11=PANES_y10+PANE_Height*PANES_Row;
	const	int			PANES_x20=PANES_x11+PANE_Width*10;
	const	int			PANES_y20=PANES_y10;
	const	int			PANES_x21=PANES_x20+PANE_Width*PANES_Col;
	const	int			PANES_y21=PANES_y20+PANE_Height*PANES_Row;
	int		PaneBin1[PANES_Row][PANES_Col];
	int		PaneBin2[PANES_Row][PANES_Col];

	const		int			N=PANES_Row*PANES_Col;	//神经元数目
	int			Input[N];		//网络初始输入
	int			Output[N];		//网络输出
	int			Threshold[N];	//神经元阈值
 	int			Weight[N][N];	//连接权
	const		int			SAM=2;	

	int		SamNum=0;
	int		Sample[SAM][N]={
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1, 1, 1, 1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
	};
/*
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1, 1, 1, 1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1,-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1, 1, 1,-1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1,-1,-1,-1, 1, 1,-1,-1,-1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1,-1,-1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1, 1, 1, 1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1, 1, 1,-1,-1, 1, 1, 1,-1,-1,-1, 1, 1, 1, 1, 1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1,-1,-1,-1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1, 1, 1, 1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1, 1,-1, 1, 1,-1,-1,-1,-1, 1, 1,-1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1, 1, 1, 1,-1,-1,-1, 1, 1, 1, 1, 1, 1, 1,-1,-1, 1, 1, 1,-1,-1,-1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1,-1,-1,-1, 1, 1, 1, 1, 1,-1,-1},
	{  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1,-1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1, 1,-1,-1,-1,-1,-1, 1,-1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1, 1, 1, 1, 1, 1,-1,-1}
	};*/

/*
#define MulArrayToPonit(array,point)
{
	int iixx,jjyy;
	point= (int**) calloc(PANES_Row, sizeof(int*));
	for (iixx=0; iixx<PANES_Row; iixx++) {
		point[iixx]=(int*) calloc(PANES_Col, sizeof(int));
	}
	for(iixx=0; iixx<PANES_Row; iixx++){
		for(jjyy=0; jjyy<PANES_Col; jjyy++){
			point[iixx][jjyy]=array[SamNum][iixx*PANES_Col+jjyy];
		}
	}
}	
*/
#define MulArrayToPonit(array,point) {int iixx,jjyy;point= (int**) calloc(PANES_Row, sizeof(int*));for (iixx=0; iixx<PANES_Row; iixx++) {point[iixx]=(int*) calloc(PANES_Col, sizeof(int));}for(iixx=0; iixx<PANES_Row; iixx++){for(jjyy=0; jjyy<PANES_Col; jjyy++){point[iixx][jjyy]=array[SamNum][iixx*PANES_Col+jjyy];}}}	
/////////////////////////////////////////////////////////////////////////////
// CDlgHop dialog


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

}


void CDlgHop::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgHop)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgHop, CDialog)
	//{{AFX_MSG_MAP(CDlgHop)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_PAINT()
	ON_BN_CLICKED(IDC_BUTTON_Input, OnBUTTONInput)
	ON_BN_CLICKED(IDC_BUTTON_GetBin, OnBUTTONGetBin)
	ON_BN_CLICKED(IDC_BUTTON_Sample, OnBUTTONSample)
	ON_BN_CLICKED(IDC_BUTTON_Study, OnBUTTONStudy)
	ON_BN_CLICKED(IDC_BUTTON_quan, OnBUTTONquan)
	ON_BN_CLICKED(IDC_BUTTON_Remmber, OnBUTTONRemmber)
	ON_BN_CLICKED(IDC_BUTTON_Quest, OnBUTTONQuest)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgHop message handlers

BOOL CDlgHop::OnInitDialog() 
{
	CDialog::OnInitDialog();
	pTable1=new CPanes(this,PANES_x10,PANES_y10,PANES_Row,PANES_Col,PANE_Height,PANE_Width,RGB(0,0,0),RGB(0,150,0),RGB(0,230,0),RGB(0,0,0),1,"书写区");
	pTable2=new CPanes(this,PANES_x20,PANES_y20,PANES_Row,PANES_Col,PANE_Height,PANE_Width,RGB(0,0,0),RGB(0,150,0),RGB(0,230,0),RGB(0,0,0),1,"识别区");

	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
void CDlgHop::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	pTable1->Draw();
	pTable2->Draw();
	// Do not call CDialog::OnPaint() for painting messages
}


void CDlgHop::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	pTable1->DoLButtonDown(point);
	//pTable2->DoLButtonDown(point);

	CDialog::OnLButtonDown(nFlags, point);
}

void CDlgHop::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	pTable1->DoLButtonUp(point);
	//pTable2->DoLButtonUp(point);
}

void CDlgHop::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	pTable1->DoMouseMove(point);
	//pTable2->DoMouseMove(point);
	
	CDialog::OnMouseMove(nFlags, point);
}


void CDlgHop::OnBUTTONInput() 
{
		pTable1->Clear();
}

void CDlgHop::OnBUTTONGetBin() 
{
	// TODO: Add your control notification handler code here
	pTable1->ToFile("HopfieldSample.txt",",");

	HWND h=::FindWindowEx(NULL,NULL,NULL,"Microsoft Internet Explorer");
	::ShellExecute(h,"open","HopfieldSample.txt",NULL,NULL,SW_SHOWNORMAL);
}

void CDlgHop::OnBUTTONSample() 
{
	// TODO: Add your control notification handler code here
	int **table;
	MulArrayToPonit(Sample,table);
	pTable1->Fill(table);
	//pTable1->useFuncPoint( OnBUTTONStudy );

	SamNum=(SamNum+1)%SAM;
	CString s;
	s.Format("→样本%d",SamNum+1);
	this->SetDlgItemText( IDC_BUTTON_Sample,s);

}

void CDlgHop::OnBUTTONStudy() 
{
	// TODO: Add your control notification handler code here
	int	i,j,k;
	int	w;

  for (i=0; i<N; i++) {
	Threshold[i]=0;
    for (j=0; j<N; j++) {
      w = 0;
      if (i!=j) {
        for (k=0; k<SAM; k++) {
          w += Sample[k][i] * Sample[k][j];
        }
      }
      Weight[i][j] = w;
    }
  }

  	CButton	*pBtn;
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_quan);
	pBtn->EnableWindow(TRUE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Input);
	pBtn->EnableWindow(TRUE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Remmber);
	pBtn->EnableWindow(TRUE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Study);
	pBtn->EnableWindow(FALSE);		

  	CString sWeight,s;
	s.Format("%d阶Hopfield网的连接权\n",N);
	sWeight+=s;
	for(i=0; i<N; i++){
		for(j=0; j<N; j++){
			s.Format("%d\t",Weight[i][j]);
			sWeight+=s;
		}
		sWeight+="\n";
	}
	CStdioFile out;
	out.Open("HopfieldWeight.txt", CFile::modeCreate | CFile::modeWrite);
	out.WriteString(sWeight);
	out.Close();

}

void CDlgHop::OnBUTTONquan() 
{
	// TODO: Add your control notification handler code here
	HWND h=::FindWindowEx(NULL,NULL,NULL,"Microsoft Internet Explorer");
	::ShellExecute(h,"open","HopfieldWeight.txt",NULL,NULL,SW_SHOWNORMAL);	
	
}

void CDlgHop::OnBUTTONRemmber() 
{

	CButton	*pBtn;		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Remmber);
	pBtn->EnableWindow(FALSE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Sample);
	pBtn->EnableWindow(FALSE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_quan);
	pBtn->EnableWindow(FALSE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Input);
	pBtn->EnableWindow(FALSE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Quest);
	pBtn->EnableWindow(FALSE);		
	pBtn=(CButton*)GetDlgItem(IDCANCEL);
	pBtn->EnableWindow(FALSE);
	// TODO: Add your control notification handler code here
	const	int		MAX=N*50;
	int	Change[MAX],Changes;
	int	ChangeIndex=0;
	int	i,j;
	for(i=0; i<MAX; i++){
		Change[i]=1;
	}

	/**********************************
	设置网络的初始状态;
	从网络中随机选取一个神经元;
	求出神经元i所有输入的加权和;
	计算神经元i在图t+1时刻的输出值;
	神经元i外的其它神经元的所有输出值不变;
	如果网络没进入稳定状态,则随机选取下一个神经元;
	**********************************/

	//设置网络的初始状态;
	pTable1->Get(Output);
	//从网络中随机选取一个神经元r;
	int		r;
	int		Hr;
	int		LastOutput_r;
	int		Cy=0;
	int		row,col;
	CString s;
	srand(time(0)); //srand(4711);
RANDOM_SELECT:
	r=rand()%N+0; //0~N-1
	//求出神经元r所有输入的加权和;
	Hr=0;
	for(j=0; j<N; j++){
		if(j!=r){
			Hr+=(Weight[r][j]*Output[j]);
		}
	}
	Hr-=Threshold[r];
	//计算神经元r在图t+1时刻的输出值;
	LastOutput_r=Output[r];
	Output[r]=(Hr>=0)? 1:-1;
	Change[ChangeIndex]=(Output[r]==LastOutput_r)? 0:1;
	ChangeIndex=(ChangeIndex+1)%MAX;
	//神经元i外的其它神经元的所有输出值不变;
	//如果网络没进入稳定状态,则随机选取下一个神经元;
	//<<<<<<<<<<<<<<<<<<<<<<<<<<<<DEBUG<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	Cy++;
	if(Cy==1){
		pTable2->Fill(Output);
		this->Invalidate(TRUE);
	}
	if(Cy<(N*10) || Cy%5==0){
		for(i=0; i<1000; i++)
			for(j=0; j<(MAX/Cy); j++);
		row=r/PANES_Col;
		col=r%PANES_Col;
		pTable2->Draw(row,col,Output[r]);
		this->Invalidate(TRUE);
	}
	//<<<<<<<<<<<<<<<<<<<<<<<<<<<<DEBUG<<<<<<<<<<<<<<<<<<<<<<<<<<<<

	Changes=0;
	for(i=0; i<MAX; i++){
		Changes+=Change[i];
	}
	if(Changes>0)
		goto	RANDOM_SELECT;
	
	//s.Format("总循环次数=%d",Cy);
	//::AfxMessageBox(s);
	
	pTable2->Draw();
	this->Invalidate(TRUE);


	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Remmber);
	pBtn->EnableWindow(TRUE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Sample);
	pBtn->EnableWindow(TRUE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_quan);
	pBtn->EnableWindow(TRUE);		
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Input);
	pBtn->EnableWindow(TRUE);	
	pBtn=(CButton*)GetDlgItem(IDC_BUTTON_Quest);
	pBtn->EnableWindow(TRUE);		
	pBtn=(CButton*)GetDlgItem(IDCANCEL);
	pBtn->EnableWindow(TRUE);		
		

}

void CDlgHop::OnBUTTONQuest() 
{
	// TODO: Add your control notification handler code here
	CString	s;
	s="";
	s+="【问题】\n";
	s+="本Hopfield网的原意在于识别鼠标书写的数字0~9共10个数字。\n";
	s+="尽管本网具有99个神经元,最多可记忆99×0.15=15个模式,\n";
	s+="但是本网最多只能正确记忆2个模式(数字)。估计的原因:\n";
	s+="建立连接权的方法为不够好的内积法。\n";
	MessageBox(s,"Hopfield",MB_ICONINFORMATION);
}

⌨️ 快捷键说明

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