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

📄 elman.cpp

📁 该算法为Elman 网络算法
💻 CPP
字号:
// Elman.cpp: implementation of the CElman class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Elman.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CElman::CElman()
{
NI=6;
NO=1;
NH=12;
NSample=3043;
NStruct=12;
LoopTimes=600;
n=0.9;
A=0.1;

}

CElman::~CElman()
{

}

void CElman::InitiateMatrix()
{
W0=new double* [NStruct];
DW0=new double* [NStruct];
DW00=new double* [NStruct];
a0=new double* [NStruct];
for(unsigned int i=0;i<NStruct;i++)
{
W0[i]=new double[NH];
DW0[i]=new double[NH];
DW00[i]=new double[NH];
a0[i]=new double[NH];
}

W1=new double* [NI];//输入层到隐含层的权值 
DW1=new double* [NI];//每一轮输入层到隐含层的权值的变化量 
DW11=new double* [NI];//上一轮对连接权值的修整量
a1=new double* [NI];

for(unsigned int i1=0;i1<NI;i1++)
{
W1[i1]=new double[NH];
DW1[i1]=new double[NH];
DW11[i1]=new double[NH];
a1[i1]=new double[NH];
}


W2=new double* [NH];// 隐含层到输出层的权值
DW2=new double* [NH];//每一轮 隐含层到输出层的权值的变化量
DW22=new double* [NH];//上一轮对连接权值的修整量
a2=new double* [NH];

for(unsigned int i2=0;i2<NH;i2++)
{
W2[i2]=new double[NO];
DW2[i2]=new double[NO];
DW22[i2]=new double[NO];
a2[i2]=new double[NO];
}
//三层神经元的输入


Pi=new double* [NSample];
Po=new double* [NSample];
Ph=new double* [NSample];
Xh=new double* [NSample];

Xo=new double* [NSample];

//神经网络的期望输出
T=new double* [NSample];
XStructure=new double* [NSample];

Qh=new double* [NSample];//隐层和输出层神经元的输出
Qo=new double* [NSample];//对应于各连接值的delta
PrePi=new double* [NSample];
PreT=new double* [NSample];//对应于各连接值的delta


for(unsigned int i3=0;i3<NSample;i3++)
{
Ph[i3]=new double[NH];
Pi[i3]=new double[NI];
Po[i3]=new double[NO];
T[i3]=new double[NO];
Xh[i3]=new double[NH];

Xo[i3]=new double[NO];

XStructure[i3]=new double[NStruct];
Qh[i3]=new double[NH];
Qo[i3]=new double[NO];
PrePi[i3]=new double[NI];
PreT[i3]=new double[NO];
}
XhOld=new double* [NSample+1];
for(unsigned int i4=0;i4<NSample+1;i4++)
{
XhOld[i4]=new double[NH];
}
XOldstructure=new double* [NSample+1];
for(unsigned int i5=0;i5<NSample+1;i5++)
{
	XOldstructure[i5]=new double[NStruct];
}
YU_ON=new double [NO];
YU_HN=new double [NH];
Error=new double [LoopTimes];//误差
SumP=new double [NI];
SumT=new double [NO];
VARP=new double [NI];
meanp=new double [NI];
STDP=new double [NI];
meanT=new double [NO];
VART=new double [NO];
STDT=new double [NO];
minP=new double [NI];
maxP=new double [NI];
minT=new double [NO];
maxT=new double [NO];
}
void CElman::InitializeZero()
{
	for(unsigned  int i=0; i<NSample; i++)
	{
		for(unsigned  int j=0; j < NI; j++)
		{
		PrePi[i][j]=0.0;
		Pi[i][j]=0.0;
		}

		for(unsigned  int j1=0; j1 < NH; j1++)
		{
		Ph[i][j1]=0.0;
		Qh[i][j1]=0.0;
		Xh[i][j1]=0.0;

		}
		for(unsigned  int j2=0; j2 < NO; j2++)
		{
			Qo[i][j2]=0.0;
			Xo[i][j2]=0.0;
			Po[i][j2]=0.0;
			T[i][j2]=0.0;
			PreT[i][j2]=0.0;
		}
		for(unsigned  int j3=0; j3 <NStruct; j3++)
		{

			XStructure[i][j3]=0.0;
		
		}
	}
	for(unsigned  int ih=0; ih<NSample+1; ih++)
	{		
		for(unsigned  int jh=0; jh < NH; jh++)
		{

		XhOld[ih][jh]=0.0;
		}
		for(unsigned  int jstr=0; jstr <NStruct; jstr++)
		{
		XOldstructure[ih][jstr]=0.0;
		}
	}
		

		for(unsigned  int i3=0; i3 < NO; i3++)
		{
		SumT[i3]=0.0;
		VART[i3]=0.0;
		meanT[i3]=0.0;
		minT[i3]=0.0;
		maxT[i3]=0.0;
		STDT[i3]=0.0;
		YU_ON[i3]=0.0;
		}
		for(unsigned  int i4=0; i4 < NI; i4++)
		{
		SumP[i4]=0.0;
		VARP[i4]=0.0;
		minP[i4]=0.0;
		maxP[i4]=0.0;
		meanp[i4]=0.0;
		STDP[i4]=0.0;
		}
		for(unsigned  int i2=0; i2 < NH; i2++)
		{
		YU_HN[i2]=0.0;
		}
		for(unsigned  int i5=0; i5 <LoopTimes; i5++)
		{
			Error[i5]=0.0;
		}
}



void CElman::initiatewb()
{
	srand( (unsigned)time( NULL ) );//意思是每次产生的随机数都不相同.
	for(unsigned  int i=0; i<NH; i++)
	{
		for(unsigned  int j=0; j < NI; j++)
		{
			W1[j][i]=((float)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX))*3;

			DW1[j][i]=0;
			DW11[j][i]=0;
			a1[j][i]=0.5;
		}
		//结构层
		for(unsigned  int j0=0; j0<NStruct; j0++)
		{
			W0[j0][i]=((float)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX))*3;
			DW0[j0][i]=0;
			DW00[j0][i]=0;
			a0[j0][i]=0.5;
		}

	//	YU_HN[i] = ((float)(::rand()) / (float)(RAND_MAX)) * 0.2f - 0.1f;  //第一隐层阈值初始化 ,-0.1 ~ 0.1 之间
	}  

	for(unsigned  int j1=0; j1 < NO; j1++)
		for(unsigned  int i1=0; i1 < NH; i1++)
		{
			{
			W2[i1][j1]=((float)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX))*3;
			DW2[i1][j1]=0;
			DW22[i1][j1]=0;
			a2[i1][j1]=0.5;
		//	V[i][j]= ((float)(::rand()) / (float)(RAND_MAX)) * 2.0f - 1.0f; //初始化隐层到输出层的权值,随机模拟0 和 1 -1
			}
		//	YU_ON[j1] = ((float)(::rand()) / (float)(RAND_MAX)) * 0.2f - 0.1f; //输出层阈值初始化 ,-0.01 ~ 0.01 之间
		}
}


void CElman::SetFreeFinal()
{
	delete[] STDT;
	delete[] VART;
	delete[] meanT;
	delete[] minT;
	delete[] maxT;
	delete[] minP;
	delete[] maxP;
	delete[] STDP;
	delete[] meanp;
	delete[] VARP;
	delete[] SumT;
	delete[] SumP;
	delete[] Error;
	delete[] YU_HN;
	delete[] YU_ON;
	for(unsigned int i4=0;i4<NSample+1;i4++)
	{
		delete[] XOldstructure[i4];
		delete[] XhOld[i4];

	}
		delete[] XhOld;
		delete[] XOldstructure;


	for(unsigned int i3=0;i3<NSample;i3++)
	{
		delete[] Pi[i3];
		delete[] Po[i3];
		delete[] Ph[i3];
		delete[] Xo[i3];
		delete[] Xh[i3];

		
		delete[] XStructure[i3];
		delete[] Qh[i3];
		delete[] Qo[i3];
		delete[] PrePi[i3];
		delete[] PreT[i3];
		delete[] T[i3];
	}

		delete[] T;
		delete[] PreT;
		delete[] PrePi;
		delete[] Qo;
		delete[] Qh;
		delete[] XStructure;

		delete[] Xh;
		delete[] Xo;
		delete[] Ph;
		delete[] Po;
		delete[] Pi;		
	for(unsigned int i2=0;i2<NH;i2++)
	{
		delete[] W2[i2];
		delete[] DW2[i2];
		delete[] DW22[i2];
		delete[] a2[i2];
	}
	delete[] a2;
	delete[] DW22;
	delete[] DW2;
	delete[] W2;
	for(unsigned int i1=0;i1<NI;i1++)
	{
		delete[] W1[i1];
		delete[] DW1[i1];
		delete[] DW11[i1];
		delete[] a1[i1];
	}
	delete[] a1;
	delete[] DW11;
	delete[] DW1;
	delete[] W1;	
	for(unsigned int i=0;i<NStruct;i++)
	{
		delete[] W0[i];
		delete[] DW0[i];
		delete[] DW00[i];
		delete[] a0[i];
	}
	delete[] a0;
	delete[] DW00;
	delete[] DW0;
	delete[] W0;
}

void CElman::DemoInput()
{

ifstream GetTrainingData ( "训练样本.txt", ios::in );

        for(unsigned int m=0;m<NSample;m++)
        {
                for(unsigned int i=0;i<NI;i++)
                {
                        GetTrainingData>>Pi[m][i];  //取得输入数据

                }
                for(unsigned int j=0;j<NO;j++)
                {
                        GetTrainingData>>T[m][j];  //取得输出数据//
                }
        }

        GetTrainingData.close();

}




void CElman::Prestd()
{

	for (unsigned int i0=0;i0<NI;i0++)
	{
	
	SumP[i0]=0;
	//		SumP=new double[i0];
		for(unsigned int m0=0;m0<NSample;m0++)
			{
				SumP[i0]+=Pi[m0][i0];
			}
			meanp[i0]=SumP[i0]/NSample;

	}

	for (unsigned int i1=0;i1<NO;i1++)
	{
		SumT[i1]=0;
		for(unsigned int m1=0;m1<NSample;m1++)
			{
				SumT[i1]+=T[m1][i1];
			}
		meanT[i1]=SumT[i1]/NSample;
	}

	for (unsigned int i2=0;i2<NI;i2++)
	
	{
		VARP[i2]=0;
		for (unsigned int m2=0;m2<NSample;m2++)
		{
			VARP[i2]+=(Pi[m2][i2]-meanp[i2])*(Pi[m2][i2]-meanp[i2]);
		//RESID = X - MEAN(X) and N is LENGTH(X).
		}
			VARP[i2]=VARP[i2]/(NSample-1);
		//VAR(X) = SUM(RESID.*CONJ(RESID)) / (N-1)
			STDP[i2]=sqrt(VARP[i2]);
	}

	for (unsigned int i3=0;i3<NO;i3++)
	{
		VART[i3]=0;
		for (unsigned int m3=0;m3<NSample;m3++)
		{
			VART[i3]+=(T[m3][i3]-meanT[i3])*(T[m3][i3]-meanT[i3]);
		//RESID = X - MEAN(X) and N is LENGTH(X).
		}
			VART[i3]=VART[i3]/(NSample-1);
		//VAR(X) = SUM(RESID.*CONJ(RESID)) / (N-1)
			STDT[i3]=sqrt(VART[i3]);
	}
	for (unsigned int m4=0;m4<NSample;m4++)
	{
		for (unsigned int i4=0;i4<NI;i4++)
		{
			PrePi[m4][i4]=(Pi[m4][i4]-meanp[i4])/STDP[i4];
	
		}
	for (unsigned int i5=0;i5<NO;i5++)
	{
			
		PreT[m4][i5]=(T[m4][i5]-meanT[i5])/STDT[i5];
	}
}
}

double CElman::cal(double d,int index)//s型激励函数
{
	switch(index)
	{
	case 0://logsig
 
	d=-d*u;
	d=exp(d);
	d=1/(1+d);
	return d;
 
	case 1://tansig
		d=2/(1+exp(-2*d))-1;
 	return d;    
	default:
   	    return d;
}
}

void CElman::forward()//计算神经元的delta,误差公式
{

for(unsigned  int i=0;i<NSample;i++)
{
	for(unsigned  int j=0; j< NO; j++)
	{
		//	Qo[i][j]=-(PreT[i][j]-Xo[i][j])*derivecal(Xo[i][j],2);//输出层的修正
			Qo[i][j]=(PreT[i][j]-Xo[i][j])*derivecal(Po[i][j],1);//输出层的修正
//Qo[i][j]=-(PreT[i][j]-Xo[i][j]);
	}
	for(unsigned  int j1=0; j1< NH; j1++)
	{
		Qh[i][j1]=0;

		for(unsigned  int k=0; k< NO; k++)
		Qh[i][j1]+=Qo[i][k]*W2[j1][k];
	//	Qh[i][j1]=Qh[i][j1]*derivecal(Xh[i][j1],2);
				Qh[i][j1]=Qh[i][j1]*derivecal(Ph[i][j1],1);
	}
}

}

double CElman::derivecal(double d,int index)

//s型激励函数求导
{
	switch(index)
	{
	case 0://logsig
 
		return u*d*(1-d);
 
	case 1:
		return 1.0-d*d;
	case 2:
		return 1.0;
}

}

void CElman::amend()//权值修正,阈值修正
{
	double D0,D,D1;
	for(unsigned  int i0=0; i0< NH; i0++)
	{

		for(unsigned  int j0=0; j0< NI; j0++)
		{
			DW1[j0][i0]=0;
		//	YU_HN[i0]=0;
		}
		for(unsigned  int k0=0; k0< NO; k0++)
		{
			DW2[i0][k0]=0;
		//	YU_ON[k0]=0;//输出层阈值
		}
	}

//结构层
	
	for(unsigned  int i2=0; i2< NStruct; i2++)
	{
	for(unsigned  int j=0; j< NH; j++)
		{	
			for(unsigned  int k=0;k<NSample;k++)
			{
				DW0[i2][j]+=Qh[k][j]*XStructure[k][i2];
			}
				D0=DW0[i2][j]*DW00[i2][j];
				a0[i2][j]=newa(a0[i2][j],D0);
				W0[i2][j]+=a0[i2][j]*(n*DW0[i2][j]+(1-n)*DW00[i2][j]);
				DW00[i2][j]=DW0[i2][j];
		}
	}
	for(unsigned  int i=0; i< NI; i++)
	{
		for(unsigned  int j=0; j< NH; j++)
		{
		
			for(unsigned  int k=0;k<NSample;k++)
			{
				DW1[i][j]+=Qh[k][j]*PrePi[k][i];
			}
				D=DW1[i][j]*DW11[i][j];
				a1[i][j]=newa(a1[i][j],D);
				W1[i][j]+=a1[i][j]*(n*DW1[i][j]+(1-n)*DW11[i][j]);
				DW11[i][j]=DW1[i][j];
		}
/*
	for(unsigned  int jb=0; jb< NH; jb++)
		{
			for(unsigned  int kb=0;kb<NSample;kb++)
			{
				YU_HN[jb]+=a1[i][jb]*Qh[kb][jb];
			}
		}*/
	}		


	for(unsigned  int i1=0; i1< NH; i1++)
	{
		for(unsigned  int j1=0; j1< NO; j1++)
		{

			for(unsigned  int k1=0;k1<NSample;k1++)
			{
				DW2[i1][j1]+=Qo[k1][j1]*Xh[k1][i1];
			}
				D1=DW2[i1][j1]*DW22[i1][j1];
				a2[i1][j1]=newa(a2[i1][j1],D1);
				W2[i1][j1]+=a2[i1][j1]*(n*DW2[i1][j1]+(1-n)*DW22[i1][j1]);
				DW22[i1][j1]=DW2[i1][j1];
		}
/*
	for(unsigned  int j3=0; j3< NO; j3++)
		{
			for(unsigned  int k3=0;k3<NSample;k3++)
			{
				YU_ON[j3]+=a2[i1][j3]*Qo[k3][j3];//错误
			}
		}*/
	}
	
}

double CElman::newa(double a, double D)//学习速率自动调节
{
	if(D>0)//当最近两次对权值调整方向相同,则为正
	{
		if(a<=0.04)
			a=a*2;
		else
			a=0.08;
	}
	else
		if(D<0)
		{
			if(a>=0.02)
				a=a/2;
			else
				a=0.01;
		}
		return a;
	}

void CElman::Simulate()
{
unsigned int j;
j=5;
}





void CElman::proceed(unsigned int Times)//各层输入输出
{

	Error[Times]=0.0;

	

	for(unsigned int i=0;i<NSample;i++)
	{
	//结构层输出
			for(unsigned int j0=0; j0 < NStruct; j0++)
			{
	//	XStructure[i][j]=0;
	//	for(unsigned int k=0; k< NH; k++)//结构层神经元个数
	//	{
			XStructure[i][j0]=XhOld[i][j0]+gaincoffi*XOldstructure[i][j0];//结构层输出
	
	//	}
			XOldstructure[i][j0]=XStructure[i][j0];
			}

		for(unsigned int j1=0; j1 < NH; j1++)
		{
			Ph[i][j1]=0;
			for(unsigned int m1=0; m1< NStruct; m1++)
			{		
				Ph[i][j1]+=XStructure[i][m1]*W0[m1][j1];//隐节点输入
			}
			for(unsigned int k1=0; k1< NI; k1++)
			{
				Ph[i][j1]+=PrePi[i][k1]*W1[k1][j1];
			}
	//		Xh[i][j1]=cal(Ph[i][j1]-YU_HN[j1]);//隐节点输出
			Xh[i][j1]=cal(Ph[i][j1],1);
			XhOld[i][j1]=Xh[i][j1];
		}


		for(unsigned int j2=0; j2 < NO; j2++)
		{
			Po[i][j2]=0;
			for(unsigned int k=0; k< NH; k++)
			{
		//	Po[i][j2]+=Xh[i][k]*W2[k][j2];
			Po[i][j2]+=Xh[i][k]*W2[k][j2];
			}
		//	Xo[i][j2]=cal(Po[i][j2]-YU_ON[j2]);
				Xo[i][j2]=cal(Po[i][j2],1);
			//Xo[i][j2]= Po[i][j2] ;
	    	Error[Times]+=(Xo[i][j2]-PreT[i][j2])*(Xo[i][j2]-PreT[i][j2])/2;
		}

	}
Error[Times]=Error[Times]/NSample;					
	}



⌨️ 快捷键说明

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