📄 inputwnd.cpp
字号:
// InputWnd.cpp : implementation file
//
#include "stdafx.h"
#include "DigitBp.h"
#include "InputWnd.h"
#include ".\inputwnd.h" //?
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CInputWnd
IMPLEMENT_DYNCREATE(CInputWnd, CWnd)
CInputWnd::CInputWnd()
: m_bTrain(false) //
{
//背景色画刷
m_brBack.CreateSolidBrush (RGB(255,255,255));
//方块填充画刷
m_brSquare.CreateSolidBrush (RGB(255,0,0));
//网格线画刷
m_hPen.CreatePen (PS_SOLID,1,RGB(0,100,192));
m_bInitDraw=false;
//初始化输入矩阵
for(int i=0;i<LEN;i++)
for(int j=0;j<LEN;j++)
{
m_bArray[i][j]=0;
m_InputArray[i][j]=0;
}
//((CComboBox*)GetDlgItem(IDC_COMBO2))->SetCurSel(0);
EnableAutomation(); ////自动生成,na mei
// To keep the application running as long as an OLE automation
// object is active, the constructor calls AfxOleLockApp.
AfxOleLockApp(); ////
}
CInputWnd::~CInputWnd()
{
if(m_hFile!=INVALID_HANDLE_VALUE)
{
if (m_bTrain){
OVERLAPPED Overlapped={0};
DATA d;
memcpy(d.e ,e,sizeof(E)*10);
memcpy(&(d.WE),&WE,sizeof(WEIGHT));
//把训练过的权值写回文件
::WriteFile (m_hFile,&d,sizeof(DATA),NULL,&Overlapped);
}
::CloseHandle(m_hFile);
}
// To terminate the application when all objects created with
// with OLE automation, the destructor calls AfxOleUnlockApp.
AfxOleUnlockApp(); ////
}
void CInputWnd::OnFinalRelease() ////
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CWnd::OnFinalRelease();
}
BEGIN_MESSAGE_MAP(CInputWnd, CWnd)
//{{AFX_MSG_MAP(CInputWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CInputWnd, CWnd) ////
//{{AFX_DISPATCH_MAP(CInputWnd)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP() ////
// Note: we add support for IID_IInputWnd to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {650C1162-3399-41A3-8A07-D3B271A3DE60}
static const IID IID_IInputWnd = ////
{ 0x650c1162, 0x3399, 0x41a3, { 0x8a, 0x7, 0xd3, 0xb2, 0x71, 0xa3, 0xde, 0x60 } };
BEGIN_INTERFACE_MAP(CInputWnd, CWnd)
INTERFACE_PART(CInputWnd, IID_IInputWnd, Dispatch)
END_INTERFACE_MAP()
// {8748E37B-AF4D-4E8A-BBC4-B1CD7A783B37}
IMPLEMENT_OLECREATE(CInputWnd, "DigitBp.InputWnd", 0x8748e37b, 0xaf4d, 0x4e8a, 0xbb, 0xc4, 0xb1, 0xcd, 0x7a, 0x78, 0x3b, 0x37) ////
/////////////////////////////////////////////////////////////////////////////
// CInputWnd message handlers
bool CInputWnd::ClearInput()
{
for(int i=0;i<LEN;i++)
for(int j=0;j<LEN;j++)
m_InputArray[i][j]=0;
return false;
}
void CInputWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
DrawInputWnd(&dc); //
// Do not call CWnd::OnPaint() for painting messages
}
bool CInputWnd::DrawInputWnd(CPaintDC *pDC)
{
CBrush *pOldBr=pDC->SelectObject (&m_brBack);
float sizeHeight=0.0;
float sizeWidth=0.0;
float newsize=0.0;
this->GetClientRect(&m_rectThis);
sizeHeight=m_rectThis.Height ()/LENF;//求出方块的长
float x=0.0;
sizeWidth=m_rectThis.Width ()/LENF;//方块的宽
float y=0.0;
if(m_bInitDraw==false){ //看方块是否已经被写上
for(int i=0;i<LEN;i++)
{
for(int j=0;j<LEN;j++)
{
m_rectArray[i][j].left =x;
m_rectArray[i][j].right =m_rectArray[i][j].left+sizeWidth;
m_rectArray[i][j].top =y;
m_rectArray[i][j].bottom =m_rectArray[i][j].top+sizeHeight ;
y=y+sizeHeight;
}
y=0.0;
x=x+sizeWidth;
}
m_bInitDraw=true;
}
pDC->Rectangle (&m_rectThis);
pDC->SelectObject (&m_hPen);
newsize=0;
for(int q=0;q<=LEN;q++,newsize+=sizeHeight)
{
pDC->MoveTo (0,newsize);
pDC->LineTo (m_rectThis.Width (),newsize); //画背景网格
}
newsize=0;
for(int r=0;r<=LEN;newsize+=sizeWidth,r++)
{
pDC->MoveTo (newsize,0);
pDC->LineTo (newsize,m_rectThis.Height ()); //画背景网格
}
pDC->SelectObject (&m_brSquare);
for(int i=0;i<LEN;i++)
for(int j=0;j<LEN;j++)
{
if(m_bArray[i][j]==1)
pDC->Rectangle (&m_rectArray[i][j]); //填充小方块
}
pDC->SelectObject (pOldBr);
return false;
}
bool CInputWnd::GetInput(int index)
{
int iLeft=LEN,iRight=0,iTop=LEN,iBottom=0;
for(int i=0;i<LEN;i++)
{
for(int j=0;j<LEN;j++)
{
if(m_bArray[i][j]==1)
{
if (iTop>j)
iTop=j; //识别方阵的最左
if(iBottom<j)
iBottom=j; //方阵的最右
if(iLeft>i)
iLeft=i; //方阵的最上
if(iRight<i)
iRight=i; //方阵的最下
}
}
}
int xMiddle=0,yMiddle=0;
xMiddle=(iRight-iLeft)/2+1;
yMiddle=(iBottom-iTop)/2+1;
iLeft=iLeft+xMiddle; //中间点的x
iTop=iTop+yMiddle; //中间点的y
int dx=iLeft-LEN/2; //求出坐标差
int dy=iTop-LEN/2; //求出坐标差
for(int g=0;g<LEN;g++) //平移坐标
for(int j=0;j<LEN;j++)
if(m_bArray[g][j]==1)
m_InputArray[g-dx][j-dy]=1;
for(int s=0;s<LEN;s++)
for(int j=0;j<LEN;j++)
m_bArray[s][j]=0;
for(int d=0;d<LEN;d++)
for(int j=0;j<LEN;j++)
if(m_InputArray[d][j]==1)
m_bArray[d][j]=1;
this->Invalidate ();
for(int h=0,t=0;h<LEN;h++)
for(int j=0;j<LEN;j++)
{
e[index].input[t]=(int )m_InputArray[h][j];//获取输入层的值
t++;
}
///////////////////////////////////////////////////////////////////////////
// 初始化输出端 //
if(index<10)
{
for(int i=0;i<10;i++)
e[index].output [i]=0;
for(int k=0;k<index;k++);
e[index].output [k]=1;
// e[index].output [index]=1;
e[index].Figure =index;
}
/////////////////////////////////////////////////////////////////////////////
e[index].simpling =true;
{//判断是否完成采样,如果完成的话可以进入训练或者识别阶段
int i=0;
for(i=0;i<10;i++)
if(e[i].simpling==true)
continue;
else break;
if(i==10)
m_bTrain=true;
}
for(int f=0;f<LEN;f++)
for(int j=0;j<LEN;j++)
{
m_InputArray[f][j]=0;//清洁旧值
}
return false;
}
RESULT CInputWnd::Identification()
{
float Err[P];
float a[M];
float o[P];
RESULT result;
result.result =-1;
for(int c=0;c<P;c++)
{
for(int j=0;j<M;j++)
{
float sum=0;
for(int k=0;k<N;k++)
sum+=WE.v [k][j]*e[10].input [k];
a[j]=FX(sum); //隐层输出
}
for(int i=0;i<P;i++)
{
float sum=0;
for(int j=0;j<M;j++)
{
sum+=WE.w [j][i]*a[j];
}
o[i]=FX(sum); //输出
}
float errsum=0;
for(int l=0;l<P;l++)
{
Err[l]=o[l]-e[c].output [l];
errsum+=Err[l]*Err[l];
}
errsum=errsum/2.0;//求出误差
int r=0;
for(;r<P;r++)
{
//如果达到精度要求就输出
if(errsum>precision)
break;
}
if(r==P)
{
result.result =c;
result.error =errsum;
return result;
}
}
return result;
}
bool CInputWnd::Initialization()
{
OVERLAPPED Overlapped={0};
DATA d;
//判断是否存在文件来调入信息
m_hFile=::CreateFile ("info.dat",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(m_hFile!=INVALID_HANDLE_VALUE)
{
if( !ReadFile(m_hFile,&d,sizeof(DATA),NULL,&Overlapped))
{//文件为空或者存在其他原因的话用默认方式来权值初始化
InitWeight();
}
m_bTrain=true;
memcpy(e ,d.e,sizeof(E)*10);
memcpy(&WE,&(d.WE ),sizeof(WEIGHT));
}
else
//说明文件不存在,所以用默认信息来初值化
{
m_hFile=::CreateFile ("info.dat",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(m_hFile==INVALID_HANDLE_VALUE)
{
AfxMessageBox("未能够创建文件");
exit(1);
}
else
{
InitWeight();
}
}
return false;
}
void CInputWnd::InitWeight()
{
//伪随机种子
srand((unsigned)time( NULL ) );
for(int i=0;i<M;i++)
for(int j=0;j<P;j++)
{
//给隐层权值赋伪随机值
float rnd;
rnd=(rand()%100)/100.0;
WE.w [i][j]= rnd;//权值初始化。
}
for(int p=0;p<N;p++)
for(int j=0;j<M;j++)
{
//给输出层权值赋伪随机值
float rnd;
rnd=(rand()%100)/100.0;
WE.v [p][j]= rnd;//权值初始化。
}
}
void CInputWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
for(int i=0;i<LEN;i++)
{
for(int j=0;j<LEN;j++)
{
if(m_rectArray[i][j].PtInRect (point)&&m_bArray[i][j]==0)
{
m_bArray[i][j]=1;
this->InvalidateRect (&m_rectArray[i][j]);
break;
}
}
}
CWnd::OnLButtonDown(nFlags, point);
}
void CInputWnd::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(nFlags==MK_LBUTTON)
{
for(int i=0;i<LEN;i++)
{
for(int j=0;j<LEN;j++)
{
if(m_rectArray[i][j].PtInRect (point)&&m_bArray[i][j]==0)
{
m_bArray[i][j]=1;
this->InvalidateRect (&m_rectArray[i][j]);
break;
}
}
}
}
CWnd::OnMouseMove(nFlags, point);
}
int CInputWnd::Training(int index) //xunlian
{
float a[M],o[P];
float Err[P];
float errsum=0;
float tempsum=0;//总误差
float in_j[M];
float in_i[P];
for(;;)
//迭代到达到需要的精度
{
errsum=0;
for(int u=0;u<LEN;u++)
{
for(int j=0;j<M;j++)
{
in_j[j]=0;
for(int k=0;k<N;k++)
{
in_j[j]=in_j[j]+WE.v[k][j]*e[u].input [k];
}
a[j]=FX(in_j[j]);//求出矩阵a
}
for(int u=0;u<P;u++)
{
in_i[u]=0;
for(int j=0;j<M;j++)
{
in_i[u]=in_i[u]+WE.w[j][u]*a[j];
}
o[u]=FX(in_i[u]);//求出输出矩阵o
}
for(int i=0;i<P;i++)
{
Err[i]=e[u].output[i]-o[i];
tempsum+=Err[i]*Err[i];
}
errsum+=tempsum/2.0;//样本误差
tempsum=0;
for(int t=0;t<M;t++)//输出层误差调整
{
for(int i=0;i<P;i++)
{
WE.w[t][i]+=A*a[t]*Err[i]*DFX(in_i[i]);
}
}
float NewErr[M]; //隐层的误差
for(int w=0;w<M;w++)
{
float sum=0;
for(int i=0;i<P;i++)
{
sum+=WE.w[w][i]*DFX(in_i[i])*Err[i];
}
NewErr[w]=sum;
}
for(int k=0;k<N;k++)//隐层权值调整
{
for(int j=0;j<M;j++)
{
WE.v[k][j]+=A*e[u].input [k]*NewErr[j]*DFX(in_j[j]);
}
}
}
if(errsum<precision)
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -