改进的BP神经网络算法(C语言源码)

#include "stdio.h"

#include "stdlib.h"

#include "time.h"

#include "math.h"

/*********************************************

inpoints 为输入神经元个数,可改变

outpoints为输出神经元个数

defaultpoints为隐层神经元个数

datagrough为样本数据个数

**********************************************

******以下数据定义可以修改*****/

#define A 0

#define a 1

#define b 1

#define c 1

#define ALFA 0.85

#define BETA 0.2 //学习率0~1

#define Total 20000

#define inpoints 9

#define outpoints 5

#define defaultpoints 28

#define datagrough 44

#define forecastdata 4

/**********定义所需变量********/

double InpointData[datagrough][inpoints],OutpointData[datagrough][outpoints]; /* 输入输出数据*/

double InpointData_MAX[inpoints],InpointData_MIN[inpoints]; /* 每个因素最大数据*/

double OutpointData_MAX[outpoints],OutpointData_MIN[outpoints]; /* 每个因素最小数据*/

double w[defaultpoints][inpoints],limen[defaultpoints],v[outpoints][defaultpoints]; /* 连接权值、阈值*/

double dlta_w[defaultpoints][inpoints],dlta_limen[defaultpoints],dlta_v[outpoints][defaultpoints]; /* 连接权、阈值修正值*/

double defaultOutpoint[defaultpoints],Outpoint_dp[outpoints],Outpoint_ep[datagrough];

/**************************读数据文件******************************/

void ReadData()

{

FILE *fp1,*fp2;

int i,j;

if((fp1=fopen("D:\\data\\训练输入.txt","r"))==NULL)

{

printf("1can not open the file\n");

exit(0);

}

for(i=0;i

for(j=0;j

fscanf(fp1,"%lf",&InpointData[i][j]);

fclose(fp1);

if((fp2=fopen("D:\\data\\训练输出.txt","r"))==NULL)

{

printf("2can not open the file\n");

exit(0);

}

for(i=0;i

for(j=0;j

fscanf(fp2,"%lf",&OutpointData[i][j]);

fclose(fp2);

}

/*****************************************************/

/*****************************************归一化******************************************************/

void unitary()

{

int i,j;

int k=0;

for(j=0;j

{

InpointData_MAX[j]=InpointData[0][j];

InpointData_MIN[j]=InpointData[0][j];

for(i=0;i

if(InpointData_MAX[j]

InpointData_MAX[j]=InpointData[i][j];

else if(InpointData_MIN[j]>InpointData[i][j])

InpointData_MIN[j]=InpointData[i][j];

}

for(j=0;j

{

OutpointData_MAX[j]=OutpointData[0][j];

OutpointData_MIN[j]=OutpointData[0][j];

for(i=0;i

if(OutpointData_MAX[j]

OutpointData_MAX[j]=OutpointData[i][j];

else if(OutpointData_MIN[j]>OutpointData[i][j])

OutpointData_MIN[j]=OutpointData[i][j];

}

/***************将数据归一处理,处理之后的数据全部在[0,1]之间*************************/

for(j=0;j

for(i=0;i

if(InpointData_MAX[j]==0)

InpointData[i][j]=0;

else

InpointData[i][j]=(InpointData[i][j]-InpointData_MIN[j]+A)/(InpointData_MAX[j]-InpointData_ MIN[j]+A);

for(j=0;j

for(i=0;i

if(OutpointData_MAX[j]==0)

OutpointData[i][j]=0;

else

OutpointData[i][j]=(OutpointData[i][j]-OutpointData_MIN[j]+A)/(OutpointData_MAX[j]-Outpoi ntData_MIN[j]+A);

}

/*****************************************************/

/*********************初始化,随机赋初值**************************/

void Initialization()

{

int i,j;

srand((unsigned)time(NULL)); //头文件名#include

for(i=0;i

for(j=0;j

{

w[i][j]=(rand()*2.0/RAND_MAX-1)/2;

dlta_w[i][j]=0;

}

for(i=0;i

limen[i]=(rand()*2.0/RAND_MAX-1)/2;

dlta_limen[i]=0;

}

for(i=0;i

for(j=0;j

{

v[i][j]=(rand()*2.0/RAND_MAX-1)/2;

dlta_v[i][j]=0;

}

}

/**********************求单样本的计算输出误差*******************************/ void out_sub1(int t)

{

int i,j;

double defaultInpoint[defaultpoints];

double Outpoint_y[outpoints];

Outpoint_ep[t]=0;

for(i=0;i

{

double sum=0;

for(j=0;j

sum+=w[i][j]*InpointData[t][j];

defaultInpoint[i]=sum+limen[i];

defaultOutpoint[i]=1/(a+b*exp(-1*c*defaultInpoint[i]));//求O[i]

}

for(j=0;j

{

Outpoint_y[j]=0;

for(i=0;i

Outpoint_y[j]+=v[j][i]*defaultOutpoint[i];

Outpoint_dp[j]=OutpointData[t][j]-Outpoint_y[j];

Outpoint_ep[t]+=Outpoint_dp[j]*Outpoint_dp[j]/2;

}

}

/*****************************反算权值******************************************/

void out_sub2(int t)

{

int i,j,k;

double s;

for(i=0;i

s=0;

for(j=0;j

{

dlta_v[j][i]=ALFA*dlta_v[j][i]+BETA*Outpoint_dp[j]*defaultOutpoint[i]; //

s+=v[j][i]*Outpoint_dp[j];

v[j][i]+=dlta_v[j][i];

}

dlta_limen[i]=ALFA*dlta_limen[i]+BETA*defaultOutpoint[i]*(1-defaultOutpoint[i])*s;// limen[i]+=dlta_limen[i];

for(k=0;k

{

dlta_w[i][k]=ALFA*dlta_w[i][k]+BETA*defaultOutpoint[i]*(1-defaultOutpoint[i])*s*InpointDat a[t][k];//

w[i][k]=w[i][k]+dlta_w[i][k];

}

}

}

/*******************************************************/

void forecast()

{

int i,j,t,k=0;

double e,e1[forecastdata]={0}; //训练误差

double sss;

double InputData_x[forecastdata][inpoints],tp[forecastdata][outpoints];

double

defInpoint,defOutpoint[defaultpoints],y[forecastdata][outpoints];//y[forecastdata][outpoints]为网络检验输出

FILE *fp1,*fp3;

if((fp1=fopen("D:\\data\\预测输入.txt","r"))==NULL) //检验数据输入{

printf("3can not open the file\n");

exit(0);

}

for(i=0;i

for(j=0;j

fscanf(fp1,"%lf",&InputData_x[i][j]);

fclose(fp1);

if((fp3=fopen("D:\\data\\预测输出.txt","r"))==NULL) //实际检验结果输出{

printf("31can not open the file\n");

exit(0);

}

for(i=0;i

for(j=0;j

fscanf(fp3,"%lf",&tp[i][j]);

fclose(fp3);

for(j=0;j

for(i=0;i

if(InpointData_MAX[j]==0)

InputData_x[i][j]=0;

else

InputData_x[i][j]=(InputData_x[i][j]-InpointData_MIN[j]+A)/(InpointData_MAX[j]-InpointData _MIN[j]+A);

for(j=0;j

for(i=0;i

if(OutpointData_MAX[j]==0)

tp[i][j]=0;

else

tp[i][j]=(tp[i][j]-OutpointData_MIN[j]+A)/(OutpointData_MAX[j]-OutpointData_MIN[j]+A);

do

{

Initialization(); //初始化连接权值w[i][j],limen[i],v[k][i]

k=0;

do

{

e=0;

for(t=0;t

{

out_sub1(t); //正向计算网络输出

out_sub2(t); //反向计算,修正权值

e+=Outpoint_ep[t]; //计算输出误差

}

k++;

}while((k0.1));

sss=0; //中间参数

for(t=0;t

{

e1[t]=0;

for(i=0;i

{

double sum=0;

for(j=0;j

sum+=w[i][j]*InputData_x[t][j];

defInpoint=sum+limen[i];

defOutpoint[i]=1/(a+b*exp(-1*c*defInpoint));

}

for(j=0;j

{

y[t][j]=0;

for(i=0;i

y[t][j]+=v[j][i]*defOutpoint[i];

e1[t]+=(y[t][j]-tp[t][j])*(y[t][j]-tp[t][j])/2;

y[t][j]=y[t][j]*(OutpointData_MAX[j]-OutpointData_MIN[j]+A)+OutpointData_MIN[j]-A;

}

sss+=e1[t];

}

sss=sss/forecastdata;

printf(" %lf %lf\n",e,sss);

}while(sss>0.12);

}

/********************************************************/

void main()

{

int i,j,k;

FILE *fp2;

ReadData(); //读训练数据:输入和输出

unitary(); //归一化,将输入输出数据归一,结果在[0,1]中

forecast(); //检验误差

if((fp2=fopen("D:\\data\\计算权值.txt","w"))==NULL) //文件输出训练好的权值

{

printf("6can not open the file\n");

exit(0);

}

for(i=0;i

{

for(k=0;k

fprintf(fp2," %lf ",w[i][k]);

fprintf(fp2,"\n");

}

fprintf(fp2,"\n");

for(i=0;i

fprintf(fp2," %lf ",limen[i]);

fprintf(fp2,"\n\n");

for(i=0;i

{

for(j=0;j

fprintf(fp2," %lf ",v[j][i]);

fprintf(fp2,"\n");

}

fclose(fp2);

}

相关主题
相关文档
最新文档