📄 bp.cpp
字号:
// BP.cpp : Defines the entry point for the console application.
//
//---------------------------------------------------------------------------
#include <vcl.h>
#include "BP.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "time.h"
extern int N,In,ON,HN;
//---------------------------------------------------------------------------
//动态定义数组
__fastcall TBP::TBP()
{
int i;
//动态分配一维数组
e_err= new double[HN];
d_err=new double[ON];
sita=new double[HN];
gama=new double[ON];
err_m=new double[N];
abs_err=new double[ON];
Xmax=new double[In];
Xmin=new double[In];
Ymax=new double[ON];
Ymin=new double[ON];
//动态分配二维数组
W=new double*[In];
for(i=0;i<In;i++)
W[i]=new double[HN];
V=new double*[HN];
for( i=0;i<HN;i++)
V[i]=new double[ON];
X=new double*[N];
for(i=0;i<N;i++)
X[i]=new double[HN];
Y=new double*[N];
for(i=0;i<N;i++)
Y[i]=new double[ON];
H=new double*[N];
for(i=0;i<N;i++)
H[i]=new double[HN];
O=new double*[N];
for(i=0;i<N;i++)
O[i]=new double[ON];
P=new double*[N];
for(i=0;i<N;i++)
P[i]=new double[In];
T=new double*[N];
for(i=0;i<N;i++)
T[i]=new double[ON];
}
//释放内存
__fastcall TBP::~TBP()
{
//释放一维数组指针
delete [HN]e_err;
delete [ON]d_err;
delete [HN]sita;
delete [ON]gama;
delete [N]err_m;
delete [ON]abs_err;
delete Xmax;
delete Xmin;
delete Ymax;
delete Ymin;
//释放二维数组指针
for(int i=0;i<In;i++)
delete [HN]W[i];
delete [In]W;
for(int i=0;i<HN;i++)
delete [ON]V[i];
delete [HN]V;
for(int i=0;i<N;i++)
{
delete [HN]X[i];
delete [ON]Y[i];
delete [HN]H[i];
delete [ON]O[i];
delete [In]P[i];
delete [ON]T[i];
}
delete [N]X;
delete [N]Y;
delete [N]H;
delete [N]O;
delete [N]P;
delete [N]T;
}
///////////////////////////////////
//输入输出数据的初始化 //////////
//////////////////////////////////
void __fastcall TBP::LoadData(double al,double be,double Err, int Times)
{
//TODO: Add your source code here
alpha=al;
beta=be;
Pre_error=Err;
Pre_times=Times;
}
///////////////////////////
//初始化权、阈值子程序/////
///////////////////////////
void __fastcall TBP::initial()
{
//TODO: Add your source code here
int i,j,k;
//srand((unsigned)time( NULL));
//隐层权、阈值初始化//
for(j=0;j<HN;j++)
for(i=0;i<In;i++)
{
W[i][j]=(double)rand()/RAND_MAX;//隐层权值初始化
sita[j]=(double)rand()/RAND_MAX;//中间层阈值初始化
}
//输出层权、阈值初始化//
for (j=0;j<ON;j++)
for (k=0;k<HN;k++)
{
V[k][j]=(double)rand()/RAND_MAX;//第m个样本输出层权值初始化
gama[j]=(double)rand()/RAND_MAX;//输出层阈值初始化
}
//输入数据的规一化
for(j=0;j<In;j++)
{
Xmax[j]=P[0][j];
Xmin[j]=P[0][j];
for(i=0;i<N;i++)
{
if(P[i][j]>=Xmax[j])
Xmax[j]=P[i][j];
if(P[i][j]<Xmin[j])
Xmin[j]=P[i][j];
}
}
for(i=0;i<N;i++)
for(j=0;j<In;j++)
P[i][j]=(P[i][j]-Xmin[j])/(Xmax[j]-Xmin[j]);
//输出数据的归一化
for(j=0;j<ON;j++)
{
Ymax[j]=T[0][j];
Ymin[j]=T[0][j];
for(i=0;i<N;i++)
{
if(T[i][j]>=Ymax[j])
Ymax[j]=T[i][j];
if(T[i][j]<Ymin[j])
Ymin[j]=T[i][j];
}
}
for(i=0;i<N;i++)
for(j=0;j<ON;j++)
T[i][j]=(T[i][j]-Ymin[j])/(Ymax[j]-Ymin[j]);
}
/////////////////////////////////
//隐层各单元输入、输出值子程序///
/////////////////////////////////
void __fastcall TBP::H_I_O(int m)
{
//TODO: Add your source code here
double sigma;
int i,j;
for (j=0;j<HN;j++)
{
sigma=0.0;
for (i=0;i<In;i++)
sigma+=W[i][j]*P[m][i];//求隐层内积
X[m][j]=sigma - sita[j];//求隐层净输入
H[m][j]=1.0/(1.0+exp(-X[m][j]));//求隐层输出
}
}
///////////////////////////////////
//输出层各单元输入、输出值子程序///
///////////////////////////////////
void __fastcall TBP::O_I_O(int m)
{
//TODO: Add your source code here
double sigma;
for (int j=0;j<ON;j++)
{
sigma=0.0;
for (int k=0;k<HN;k++)
sigma+=V[k][j]*H[m][k];//求输出层内积
Y[m][j]=sigma-gama[j]; //求输出层净输入
O[m][j]=1.0/(1.0+exp(-Y[m][j]));//求输出层输出
}
}
////////////////////////////////////
//输出层至隐层的一般化误差子程序////
////////////////////////////////////
void __fastcall TBP::Err_O_H(int m)
{
//TODO: Add your source code here
// double abs_err[ON];//每个样本的绝对误差都是从0开始的
double sqr_err=0;//每个样本的平方误差计算都是从0开始的
for (int k=0;k<ON;k++)
{
abs_err[k]=T[m][k]-O[m][k];//求第m个样本下的第k个神经元的绝对误差
sqr_err+=(abs_err[k])*(abs_err[k]);//求第m个样本下输出层的平方误差
d_err[k]=abs_err[k]*O[m][k]*(1.0-O[m][k]);//d_err[k]输出层各神经元的一般化误差
}
err_m[m]=sqr_err/2;//第m个样本下输出层的平方误差/2=第m个样本的均方误差
}
////////////////////////////////////
//隐层至输入层的一般化误差子程序////
////////////////////////////////////
void __fastcall TBP::Err_H_I(int m)
{
//TODO: Add your source code here
double sigma;
for (int j=0;j<HN;j++)
{
sigma=0.0;
for (int k=0;k<ON;k++)
sigma+=d_err[k]*V[j][k];
e_err[j]=sigma*H[m][j]*(1-H[m][j]);//隐层各神经元的一般化误差
}
}
////////////////////////////////////////////////////////
//输出层至隐层的权值调整、输出层阈值调整计算子程序//////
////////////////////////////////////////////////////////
void __fastcall TBP::Delta_O_H(int m)
{
//TODO: Add your source code here
for (int k=0;k<ON;k++)
for (int j=0;j<HN;j++)
{
V[j][k]+=alpha*d_err[k]*H[m][j];//输出层至隐层的权值调整
gama[k]+=alpha*d_err[k];//输出层至隐层的阈值调整
}
}
/////////////////////////////////////////////////////
//隐层至输入层的权值调整、隐层阈值调整计算子程序/////
/////////////////////////////////////////////////////
void __fastcall TBP::Delta_H_I(int m)
{
//TODO: Add your source code here
for (int j=0;j<HN;j++)
for (int i=0;i<In;i++)
{
W[i][j]+=beta*e_err[j]*P[m][i];//隐层至输入层的权值调整
sita[j]+=beta*e_err[j];
}
}
/////////////////////////////////
//N个样本的全局误差计算子程序////
/////////////////////////////////
double __fastcall TBP::Err_Sum()
{
//TODO: Add your source code here
double total_err=0;
for (int m=0;m<N;m++)
total_err+=err_m[m];//每个样本的均方误差加起来就成了全局误差
return (total_err) ;
}
/////////////////////////////////
///BP算法的主体//////////////////
/////////////////////////////////
void __fastcall TBP::RunBP()
{
study=0;
sum_err=0.0;
initial(); //隐层、输出层权、阈值初始化以及输入输出数据的归一化
do
{
study++; //计算学习次数
for ( int k=0;k<N;k++)
{
H_I_O(k); //第m个学习样本隐层各单元输入、输出值
O_I_O(k); //第m个学习样本输出层各单元输入、输出值
Err_O_H(k); //第m个学习样本输出层至隐层一般化误差
Err_H_I(k); //第m个学习样本隐层至输入层一般化误差
Delta_O_H(k); //第m个学习样本输出层至隐层权阈值调整、修改
Delta_H_I(k); //第m个学习样本隐层至输入层权阈值调整、修改
} //全部样本训练完毕
sum_err=Err_Sum(); //全部样本全局误差计算
}
while(sum_err>=Pre_error&&study<=Pre_times);
}
/////////////////////////////////
///BP算法的测试//////////////////
/////////////////////////////////
void __fastcall TBP::TestBP(double Input[],TMemo* Memo1)
{
double sigma,sigma1;
int i,j,k;
AnsiString m_str;
for(i=0;i<In;i++)
Input[i]=(Input[i]-Xmin[i])/(Xmax[i]-Xmin[i]);
for (j=0;j<HN;j++)
{
sigma=0.0;
for (i=0;i<In;i++)
sigma+=W[i][j]*Input[i];//求隐层内积
X[0][j]=sigma - sita[j];//求隐层净输入
H[0][j]=1.0/(1.0+exp(-X[0][j]));//求隐层输出
}
for (j=0;j<ON;j++)
{
sigma1=0.0;
for ( k=0;k<HN;k++)
sigma1+=V[k][j]*H[0][k];//求输出层内积
Y[0][j]=sigma1-gama[j]; //求输出层净输入
O[0][j]=1.0/(1.0+exp(-Y[0][j]));//求输出层输出
}
for (j=0;j<ON;j++)
{
m_str=FormatFloat("0.0000",O[0][j]*(Ymax[j]-Ymin[j])+Ymin[j]);
Memo1->Lines->Add(m_str);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -