www.pudn.com > RBPNN.rar > CRBPNN.CPP, change:2006-06-19,size:12551b


#include 
#include 
#include"CRBPNN.H" 
#include 
#include 
#include 
 
CRBPNN::CRBPNN() 
{ 
	this->m_pN=0; 
	this->m_pD=0; 
	this->m_pC=0; 
	this->m_in=0; 
	this->m_out=0; 
	this->m_mid1=0; 
	this->m_mid2=0; 
	this->m_kernel=NULL; 
	this->m_learningalgorithm=NULL; 
 
	this->v_pNC=NULL; 
	this->v_pSort=NULL; 
	this->v_pClass=NULL; 
	this->v_pX=NULL; 
	this->v_expectD=NULL; 
	this->v_realY=NULL; 
	this->v_conS=NULL; 
	this->v_midZ1=NULL; 
	this->v_midZ2=NULL; 
	this->v_weight=NULL; 
} 
 
CRBPNN::~CRBPNN() 
{ 
	int i; 
	for(i=0;im_mid1;i++) 
		delete[] this->v_conS[i]; 
	for(i=0;im_out;i++) 
		delete[] this->v_weight[i]; 
	delete[] this->v_conS,this->v_weight,this->v_pNC; 
 
	if(this->v_realY!=NULL) 
	{ 
		for(i=0;im_pN;i++) 
			delete[] this->v_realY[i]; 
		delete[] this->v_realY; 
	} 
} 
 
void CRBPNN::Training(int pn, 
					  int pd, 
					  int pc, 
					  char* kernel, 
					  char* learning, 
					  char* sampledata) 
{ 
	if(pn>0&&pd>0&&pc>0&&kernel!=NULL&&learning!=NULL&&sampledata!=NULL) 
	{ 
		////////////////////////////////////////// 
		//初始化网络,分配空间 
		////////////////////////////////////////// 
		int i,j; 
 
		this->m_pN=pn; 
		this->m_pD=pd; 
		this->m_pC=pc; 
		this->m_in=pd; 
		this->m_kernel=kernel; 
		this->m_learningalgorithm=learning; 
		this->m_mid1=pn; 
		this->m_mid2=pc; 
		this->m_out=pc; 
		 
		this->v_pNC=new int[this->m_pC]; 
		this->v_pSort=new int[this->m_pN];		 
		this->v_pClass=new int[this->m_pN]; 
		 
		this->v_pX=new double*[this->m_pN];	 
		this->v_expectD=new double*[this->m_pN]; 
		this->v_conS=new double*[this->m_mid1]; 
		this->v_midZ1=new double*[this->m_pN]; 
		this->v_midZ2=new double*[this->m_pN]; 
		this->v_weight=new double*[this->m_out]; 
 
		for(j=0;jm_pN;j++) 
		{ 
			this->v_pX[j]=new double[this->m_in]; 
			this->v_expectD[j]=new double[this->m_out]; 
			this->v_midZ1[j]=new double[this->m_mid1]; 
			this->v_midZ2[j]=new double[this->m_mid1]; 
		} 
 
		for(j=0;jm_mid1;j++) 
			this->v_conS[j]=new double[this->m_in]; 
 
		for(j=0;jm_out;j++) 
			this->v_weight[j]=new double[this->m_mid2]; 
		 
		ifstream fin(sampledata,ios::nocreate); 
		if(fin.fail()) 
		{ 
			cerr<<"Error opening the file:"<m_pN;i++) 
		{ 
			int c; 
			fin>>c; 
	 
			this->v_pClass[i]=c;	//类别标志 
			for(j=0;jm_out;j++) 
			{ 
				if(j==(c-1))	this->v_expectD[i][j]=1; 
				else this->v_expectD[i][j]=0; 
			} 
			 
			for(j=0;jm_in;j++) 
				fin>>this->v_pX[i][j]; 
 
		 
		} 
		fin.close(); 
		 
		for(i=0;im_out;i++) 
			for(j=0;jm_mid2;j++) 
				this->v_weight[i][j]=1; 
 
		////////////////////////////////////////// 
		//训练网络,更新并记录权值 
		////////////////////////////////////////// 
 
		 
		this->CalcNumberperC(); 
		this->ChooseandSortconS();	//选取径向基函数中心矢量 
		this->CalcMidZ1();			//选择变换函数,计算隐层输出	 
		this->CalcMidZ2(); 
 
		if(strcmp(this->m_learningalgorithm,"RLSA")==0) 
			RLSA(); 
		//其他学习算法 
		//else if 
		//else if 
		//... 
 
		////////////////////////////////////////// 
		//释放空间,仅保留权值、中心控制矢量和各个变量 
		////////////////////////////////////////// 
		for(j=0;jm_pN;j++) 
			delete[] this->v_pX[j],this->v_expectD[j],this->v_midZ1[j],this->v_midZ2[j]; 
		delete[] this->v_pX,this->v_expectD,this->v_midZ1,this->v_midZ2; 
 
		delete[] this->v_pClass,this->v_pSort; 
	} 
} 
 
/*计算每个类别对应的模式个数*/ 
void CRBPNN::CalcNumberperC() 
{ 
	int c,i,j; 
	j=0; 
	for(c=1;c<=this->m_pC;c++) 
	{ 
		this->v_pNC[c-1]=0; 
		for(i=0;im_pN;i++) 
		{ 
			if(this->v_pClass[i]==c) 
			{ 
				this->v_pSort[j]=i; 
				j++; 
				this->v_pNC[c-1]++; 
			} 
		} 
	} 
} 
 
/*设置中心控制矢量,并将其按类别排好*/ 
void CRBPNN::ChooseandSortconS() 
{ 
	int i,j; 
 
	for(i=0;im_mid1;i++) 
		for(j=0;jm_in;j++)	 
			this->v_conS[i][j]=this->v_pX[this->v_pSort[i]][j]; 
} 
 
/*计算第一隐层输出*/ 
void CRBPNN::CalcMidZ1() 
{ 
	if(strcmp(this->m_kernel,"Gaussian")==0) 
	{ 
		double*  v_alpha;			//高斯形状控制参数 
		v_alpha=new double[this->m_mid1]; 
 
		for(int m=0;mm_mid1;m++) 
			v_alpha[m]=0.3;			//将v_alpha[i]设为固定值0.5 
	 
		/* 
		//将v_alpha[i]设为0、1之间的随机值 
		int m;				 
		srand((unsigned)time(NULL)); 
		for(m=0;mm_pN;t++) 
		{ 
			for(i=0;im_mid1;i++) 
			{ 
				sum=0; 
				for(j=0;jm_in;j++) 
					sum+=pow(this->v_pX[t][j]-this->v_conS[i][j],2); 
				sum=sum*1.0/(2.0*(pow(v_alpha[i],2))); 
				this->v_midZ1[t][i]=exp((-1)*sum); 
			} 
		} 
 
		delete[] v_alpha; 
	} 
	//采用其他核计算第一层隐层输出 
	//if 
	//if 
	//if 
} 
 
/*计算第二隐层输出*/ 
void CRBPNN::CalcMidZ2() 
{ 
	int i,j,k,t; 
	double sum; 
 
	for(i=0;i>m_lamda; 
		m_lamda=0.99; 
		//cout<<"请输入终止误差:"<>m_enderror; 
		m_enderror=0.01; 
		//cout<<"请输入终止次数:"<>m_endcyc; 
		m_endcyc=1000; 
 
		double *v_gain;			//卡尔曼增益 
		v_gain=new double[m_mid2]; 
 
		double **v_icorrP;		//逆相关矩阵 
		v_icorrP=new double*[m_mid2]; 
		for(i=0;im_mid2;i++) 
		{ 
			v_icorrP[i]=new double[m_mid2]; 
			for(j=0;jm_mid2;j++) 
				if(j==i) v_icorrP[i][j]=1; 
				else v_icorrP[i][j]=0; 
		} 
		 
		//迭代算法,计算权值和累计误差能量 
		do 
		{ 
			pk=int(k%this->m_pN);									//选择输入模式 
			this->CalcGain(pk,m_lamda,v_gain,v_icorrP);		//计算卡尔曼增益 
			this->CalcIcorrP(pk,m_lamda,v_gain,v_icorrP);		//计算逆相关矩阵 
			m_energyJ=this->CalcEnergyJ(pk,m_lamda,m_energyJ);	//计算累计误差能量 
			this->CalcWeight(pk,v_gain);						//更新连接权值 
			k++; 
			fout<m_enderror&&km_out;j++) 
	{ 
		sum=0; 
		for(k=0;km_mid2;k++) 
			sum+=this->v_midZ2[t][k]*this->v_weight[j][k]; 
		sum=this->v_expectD[t][j]-sum; 
	 
		for(i=0;iv_weight[j][i]=this->v_weight[j][i]+gain[i]*sum; 
	} 
} 
 
/*计算卡尔曼增益 
t:迭代的次序 
lamda:加权遗忘因子 
gain:卡尔曼增益(输出) 
icorrP:逆相关矩阵*/ 
void CRBPNN::CalcGain(int t,double lamda,double* gain,double **icorrP) 
{ 
	int i,j; 
	double g=0.0; 
	 
	for(i=0;im_mid2;i++) 
	{ 
		gain[i]=0.0; 
		for(j=0;jm_mid2;j++) 
			gain[i]+=icorrP[i][j]*this->v_midZ2[t][j]; 
	} 
 
	for(j=0;jm_mid2;j++) 
		g+=this->v_midZ2[t][j]*gain[j]; 
 
	g+=lamda; 
	for(i=0;im_mid2;i++) 
		gain[i]/=g; 
} 
 
/*迭代计算逆相关矩阵 
t:迭代的次序 
lamda:加权遗忘因子 
gain:卡尔曼增益 
icorrP:逆相关矩阵(输出)*/ 
void CRBPNN::CalcIcorrP(int t,double lamda,double *gain,double **icorrP) 
{ 
	int i,j,k; 
	double** temp1; 
	double** temp2; 
	temp1=new double*[this->m_mid2]; 
	temp2=new double*[this->m_mid2]; 
	 
	for(i=0;im_mid2;i++) 
	{ 
		temp1[i]=new double[this->m_mid2]; 
		for(j=0;jm_mid2;j++) 
			temp1[i][j]=gain[i]*this->v_midZ2[t][j]; 
	} 
 
	for(i=0;im_mid2;i++) 
	{ 
		temp2[i]=new double[this->m_mid2]; 
		for(j=0;jm_mid2;j++) 
		{ 
			temp2[i][j]=0; 
			for(k=0;km_mid2;k++) 
				temp2[i][j]+=temp1[i][k]*icorrP[k][j]; 
		} 
	} 
 
	for(i=0;im_mid2;i++) 
	{ 
		for(j=0;jm_mid2;j++) 
			icorrP[i][j]=(icorrP[i][j]-temp2[i][j])/lamda; 
	} 
 
	for(i=0;im_mid2;i++) 
		delete[] temp1[i],temp2[i]; 
	delete[] temp1,temp2; 
} 
 
/*迭代计算累积误差能量函数 
t:迭代的次序 
lamda:加权遗忘因子 
energyJ:累积误差能量*/ 
double CRBPNN::CalcEnergyJ(int t,double lamda,double energyJ) 
{ 
	int k,j; 
	double sum1,sum2; 
	 
	sum1=0; 
	for(j=0;jm_out;j++) 
	{ 
		sum2=0; 
		for(k=0;km_mid2;k++) 
			sum2+=this->v_midZ2[t][k]*this->v_weight[j][k]; 
		sum2=this->v_expectD[t][j]-sum2; 
		sum1+=pow(sum2,2); 
	} 
	return lamda*energyJ+sum1/2.0; 
} 
 
/*模式分类 
n:需要分类的模式个数 
testdata:分类数据*/ 
void CRBPNN::Classifying(int n,char* testdata) 
{ 
	if(n>0&&testdata!=NULL&&this->v_weight!=NULL) 
	{ 
		int i,j; 
		this->m_pN=n; 
		this->v_pX=new double*[this->m_pN];	 
		this->v_midZ1=new double*[this->m_pN]; 
		this->v_midZ2=new double*[this->m_pN]; 
 
		for(j=0;jm_pN;j++) 
		{ 
			this->v_pX[j]=new double[this->m_in]; 
			this->v_midZ1[j]=new double[this->m_mid1]; 
			this->v_midZ2[j]=new double[this->m_mid1]; 
		} 
 
		ifstream fin(testdata,ios::nocreate); 
		if(fin.fail()) 
		{ 
			cerr<<"Error opening the file:"<m_in;j++) 
				fin>>this->v_pX[i][j]; 
			i++; 
		}while(!fin.eof()); 
		fin.close(); 
 
		this->CalcMidZ1(); 
		this->CalcMidZ2(); 
		this->CalcOutput(); 
 
		for(j=0;jm_pN;j++) 
			delete[] this->v_pX[j],this->v_midZ1[j],this->v_midZ2[j]; 
		delete[] this->v_pX,this->v_midZ1,this->v_midZ2; 
	} 
} 
 
/*计算网络输出*/ 
void CRBPNN::CalcOutput() 
{ 
	int i,j,t; 
	 
	this->v_realY=new double*[this->m_pN]; 
	for(i=0;im_pN;i++) 
		this->v_realY[i]=new double[this->m_out]; 
 
	for(t=0;tm_pN;t++) 
	{ 
		for(j=0;jm_out;j++) 
		{ 
			v_realY[t][j]=0.0; 
			for(i=0;iv_realY[t][j]+=this->v_midZ2[t][i]*this->v_weight[j][i]; 
		} 
	} 
} 
 
/*网络输出 
pFileName:用于保存输出结果的文件名称*/ 
void CRBPNN::GetOutput(char *pFileName) 
{ 
	ofstream fout(pFileName); 
	if(fout.fail()) 
	{ 
		cerr<<"Error opening file:"<m_pN;i++) 
	{ 
		int t=0; 
		double y=this->v_realY[i][0]; 
		for(j=0;jm_out;j++) 
		{ 
			if(yv_realY[i][j]) {y=this->v_realY[i][j];t=j;} 
			fout<m_pN-1) fout<v_weight!=NULL) 
	{ 
		ofstream fout(pFileName); 
		if(fout.fail()) 
		{ 
			cerr<<"Error opening file:"<m_out;i++) 
		{ 
			for(j=0;jm_mid2;j++) 
			{ 
				fout<v_weight[i][j]; 
			} 
			fout<v_weight==NULL) 
	{ 
		ofstream fout(pFileName); 
		if(fout.fail()) 
		{ 
			cerr<<"Error opening file:"<m_out;i++) 
		{ 
			for(j=0;jm_mid2;j++) 
			{ 
				fout.precision(5); 
				fout<v_weight[i][j]; 
			} 
			fout<v_realY!=NULL) 
	{ 
		ifstream fin(ptestclass); 
		if(fin.fail()) 
		{ 
			cerr<<"Error opening file:"<m_pN;i++) 
		{ 
			fin>>d; 
			y=this->v_realY[i][0]; 
			t=0; 
			for(j=1;jm_out;j++) 
			{ 
				if(yv_realY[i][j]) {y=this->v_realY[i][j];t=j;} 
			} 
		 
			if(d==t+1) count++; 
		} 
		return count*100.0/m_pN; 
	} 
	return -1; 
}