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

📄 bp.cpp

📁 用于实现BP神经网络的C++Builder源代码
💻 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 + -