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

📄 bpnetdlg.cpp

📁 BP算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	fplot10=1;  //
	nunit[nhlayer+1]=noutattr;
	nunit[0]=ninattr;
}

void CBPNetDlg::init()
{
	int len1,len2,i;
	float *p1,*p2,*p3,*p4;
	len1=len2=0;
	nunit[nhlayer+2]=0;
	for(i=0;i<(nhlayer+2);i++)
	{
		len1+=(nunit[i]+1)*nunit[i+1];
		len2+=nunit[i]+1;
	}
	p1=(float *)calloc(len1+1,sizeof(float));//权指针
	p2=(float *)calloc(len2+1,sizeof(float));//输出指针
	p3=(float *)calloc(len2+1,sizeof(float));//误差指针
	p4=(float *)calloc(len1+1,sizeof(float));//delw指针
	
	wtptr[0]=p1;//设置初始的指针
	outptr[0]=p2;
	errptr[0]=p3;
	delw[0]=p4;
	
	for(i=1;i<(nhlayer+1);i++)//设置其余的指针值
	{
		wtptr[i]=wtptr[i-1]+nunit[i]*(nunit[i-1]+1);
		delw[i]=delw[i-1]+nunit[i]*(nunit[i-1]+1);
	}
	
	for(i=1;i<(nhlayer+2);i++)
	{
		outptr[i]=outptr[i-1]+nunit[i-1]+1;
		errptr[i]=errptr[i-1]+nunit[i-1]+1;
	}
	
	for(i=0;i<nhlayer+1;i++)//set up threshold outputs
	{
		*(outptr[i]+nunit[i])=1.0;
	}
}

void CBPNetDlg::initwt()//initialize weights with random
{//numbers between -0.5 and +0.5
	int i,j;
	for(j=0;j<nhlayer+1;j++)
		for(i=0;i<(nunit[j]+1)*nunit[j+1];i++)
		{
			*(wtptr[j]+i)=(float)random()/(float)pow(2.0,15.0)-(float)0.5;
			*(delw[j]+i)=0.0;
		}
}

long randseed=568731L;
int CBPNetDlg::random()
{
  randseed=15625L*randseed+22221L;
  return((randseed>>16)&0x7FFF);
}

int CBPNetDlg::rumelhart(int from_snum,int to_snum)//向后反馈,输出-〉输入
{
	int i,j,k,m,n,p ,offset,index,flag;
	float out;
	char *err_file="criter.dat";
	CString cstemp,s1;
	
	cnt=0;
	nsold=0;
	flag=0;
	result=CONTNE;
	
	if (fplot10==1)
		if((fp3=fopen(err_file,"w"))==NULL)
	    { 
			perror("cannot open error file");
			return -1;
		}
		do {  
			err_curr=0.0;//系统当前误差
			for(i=from_snum;i<to_snum;i++)//开始层到结束层
			{
				forward(i);//向前计算
				for(m=0; m<nunit[nhlayer+1];m++)
				{ 
					out=*(outptr[nhlayer+1]+m);//实际输出
					*(errptr[nhlayer+1]+m)=(target[i][m]-out)*(1-out)*out;//输出层的误差
				}
				//隐藏层误差计算
				for(m=nhlayer+1;m>=1;m--)
				{
					for(n=0;n<nunit[m-1]+1;n++)
					{
						*(errptr[m-1]+n)=0.0;
						for(p=0;p<nunit[m];p++)
						{
							offset=(nunit[m-1]+1)*p+n;
							*(delw[m-1]+offset)=eta*(*(errptr[m]+p))*(*(outptr[m-1]+n))
								+alpha*(*(delw[m-1]+offset));
							*(errptr[m-1]+n)+=*(errptr[m]+p)*(*(wtptr[m-1]+offset));
						}
						*(errptr[m-1]+n)=*(errptr[m-1]+n)*(1-*(outptr[m-1]+n))*(*(outptr[m-1]+n));
					}
				}
				//调整权
				for(m=1; m<nhlayer+2;m++)
				{
					for(n=0; n<nunit[m];n++)
					{
						for(p=0;p<nunit[m-1]+1;p++)
						{
							offset=(nunit[m-1]+1)*n+p;
							*(wtptr[m-1]+offset)+=*(delw[m-1]+offset);
						}
					}
				}

				ep[i]=0.0;//样本集误差
				for(m=0;m<nunit[nhlayer+1];m++)
				{
					ep[i]+=(float)fabs((target[i][m]-*(outptr[nhlayer+1]+m)));
				}
				err_curr+=ep[i]*ep[i];
			}
			
			err_curr=(float)0.5*err_curr/ninput;//改进

			if(fplot10==1)
				fprintf(fp3,"%d,%e\n",cnt,err_curr);
			cnt++;
            
			result=introspective(from_snum,to_snum);//自检过程,看是否可完成迭代
		}while(result==CONTNE);
		
		for(i=from_snum;i<to_snum;i++) forward(i);
		//结果显示
		for(i=0; i<nhlayer+1;i++){
			index=0;
			for(j=0;j<nunit[i+1];j++)
			{
				fprintf(fl,"Weights between  unit %d of layer %d ",j,i+1);
				fprintf(fl," and units of layer %d \n",i);
				for(k=0;k<nunit[i];k++)
					fprintf(fl,"%f ",*(wtptr[i]+index++));
				fprintf(fl,"\nThreshold of unit %d of layer %d is %f\n\n",j,i+1,*(wtptr[i]+index++));
			}
		}
		fprintf(fl,"\n");
			
		char t1[64],t2[64],t3[64];
		for(i=0; i<ninput;i++)
		{
			for(j=0; j<noutattr;j++)
			{
				s1.Format("  %7.6f  %7.6f",output[i][j],target[i][j]);//输出和目标
			}
			cstemp.Format(" %d ",i);//样本
			cstemp=cstemp+s1;
			
			sscanf(cstemp,"%s%s%s",t1,t2,t3);
			int index = m_ListCtrl1.InsertItem(i,t1);//在第一列中的显示
			m_ListCtrl1.SetItemText(index,1,t2);//第二列的显示 
			m_ListCtrl1.SetItemText(index,2,t3);//j的位置为所要插入的位置
		}
		return(result);
}


void CBPNetDlg::forward(int i)//向前传播,即由输入到输出
{
	int m,n,p,offset;
	float net;
	
	for(m=0;m<ninattr;m++)
		*(outptr[0]+m)=input[i][m];
	for(m=1; m<nhlayer+2;m++)
	{
		for(n=0;n<nunit[m];n++)
		{
			net=0.0;
			for(p=0; p<nunit[m-1]+1;p++)
			{
				offset=(nunit[m-1]+1)*n+p;
				net+=*(wtptr[m-1]+offset)*(*(outptr[m-1]+p));
			}
			*(outptr[m]+n)=(float)1/(float)(1+exp(-net));//激活函数公式
		}
	}
	for (n=0;n<nunit[nhlayer+1];n++)
		output[i][n]=*(outptr[nhlayer+1]+n);
}


int CBPNetDlg::introspective(int nfrom,int nto)//看迭代是否结束
{
	int i, flag;
	if(cnt>=cnt_num)//超过循环次数
		return(FEXIT);
	nsnew=0;
	flag=1;
	for(i=nfrom;(i<nto)&&(flag==1);i++)
	{
		if(ep[i]<=maxep) nsnew++;//最大干扰值
		else
			flag=0;
	}
	if((flag==1)) 
		return(SEXIT);
	if((err_curr<=maxe) )   return(SEXIT);//学习精度
	return(CONTNE);
}

void CBPNetDlg::dwrite( CString taskname )//学习结果写入
{ 
	int i,j,c;
	CString var_file_name;
	var_file_name=taskname;
	var_file_name=var_file_name+"_v.dat";
	if ((fp1=fopen(var_file_name,"w+"))==NULL)
	{
		AfxMessageBox("cannot open data file");
		return;
	}
	
	fprintf(fp1,"%u %u %u %f %f %f %f %u %u\n",
		ninput,noutattr,
		ninattr,eta,alpha,maxe,maxep,
		nhlayer,cnt_num);
	for(i=0; i<nhlayer+2;i++){
		fprintf(fp1,"%d  ",nunit[i]);
	}
	
	fprintf(fp1,"\n%d %f ",cnt,err_curr);
	fprintf(fp1,"\n");
	
	for(i=0;i<ninput;i++)
	{  
		for(j=0;j<noutattr;j++)
			fprintf(fp1,"%f  ",output[i][j]);
		fprintf(fp1,"\n");
	}
	
	if ((c=fclose(fp1))!=0)
		AfxMessageBox("\nfile cannot be closed ");
}




void CBPNetDlg::wtwrite(CString taskname)//权写入
{
	int i,j,c,k;
	CString wt_file_name;
	wt_file_name=taskname;
	wt_file_name=wt_file_name+"_w.dat";
	
	if ((fp2=fopen(wt_file_name,"w+"))==NULL)
	{
		AfxMessageBox("Cannot open data file");
		return;
	}
	k=0;
	for(i=0;i<nhlayer+1;i++)
		for(j=0;j<(nunit[i]+1)*nunit[i+1];j++){
			if(k==8){
				k=0;
				fprintf(fp2,"\n");
			}
			fprintf(fp2,"%f",*(wtptr[i]+j));
			k++;
		}
		if ((c=fclose(fp2))!=0)
			AfxMessageBox("\nfile cannot be closed ");
}

void CBPNetDlg::output_generation()
{
	int i,m,nsample;
	CString dfile,fnam;
	CString cstemp1,cstemp2,s1;
	CString cstemp;
	

	TV_ITEM tvItem;//控件风格
	tvItem.mask=TVIF_TEXT|TVIF_PARAM;//pszText和cchTextMax成员有效
	tvItem.pszText = "关于输出的相关信息";
	tvItem.cchTextMax=2;//字符大小
	TV_INSERTSTRUCT  tvInsert;//表示项目在树中的位置
	tvInsert.hParent=TVI_ROOT;//项目插入到视图的根部
	tvInsert.hInsertAfter=TVI_LAST;//在列表末插入项目
	tvInsert.item=tvItem;//定义将加入到树视图控件的项目的TV_ITEM结构
	HTREEITEM hRoot=m_TreeCtrl2.InsertItem(&tvInsert);//得到目录位置
	char ctemp[50];
	
	nsample=7;//处理数据的个数
	dfile="data.dat";
	
	cstemp.Format("学习模式为%s",task_name);	
	sscanf(cstemp,"%s",ctemp);	
	tvItem.pszText=ctemp;
	tvItem.cchTextMax=6;//字符大小
	tvInsert.hParent=hRoot;//设置父母录为hRoot
	tvInsert.item=tvItem;
	m_TreeCtrl2.InsertItem(&tvInsert);

	cstemp.Format("处理数据的个数%d",nsample);	
	sscanf(cstemp,"%s",ctemp);	
	tvItem.pszText=ctemp;
	tvItem.cchTextMax=6;//字符大小
	tvInsert.hParent=hRoot;//设置父母录为hRoot
	tvInsert.item=tvItem;
	m_TreeCtrl2.InsertItem(&tvInsert);

	cstemp.Format("处理数据文件为%s",dfile);	
	sscanf(cstemp,"%s",ctemp);	
	tvItem.pszText=ctemp;
	tvItem.cchTextMax=6;//字符大小
	tvInsert.hParent=hRoot;//设置父母录为hRoot
	tvInsert.item=tvItem;
	m_TreeCtrl2.InsertItem(&tvInsert);
	
	if((fp1=fopen(dfile,"r"))==NULL)
	{
		printf("cannot open this file\n");
		return;
	}
	
	for(i=0;i<nsample;i++)
		for(m=0;m<ninattr;m++)
			fscanf(fp1,"%f",&input[i][m]);
	
		//结果输出
        char t1[64],t2[64];
		for(i=0; i<nsample;i++)
		{
			s1=" ";
			forward(i);
			for(m=0; m<noutattr;m++)
			{
				cstemp1.Format("   %7.6f",*(outptr[nhlayer+1]+m));//输出
				s1=s1+cstemp1;
			}
			cstemp2.Format("  %d  ",i);//数据
			cstemp2=cstemp2+s1;
						    
			sscanf(cstemp2,"%s%s",t1,t2);
			int index = m_ListCtrl2.InsertItem(i,t1);//在第一列中的显示
			m_ListCtrl2.SetItemText(index,1,t2);//第二列的显示 
		}
		if((i=fclose(fp1))!=0)
			AfxMessageBox("cannot close this file\n");
}


void CBPNetDlg::dread(CString taskname)
{
	int i,c;
	CString var_file_name;
	
	var_file_name=taskname;
	var_file_name=var_file_name+"_v.dat";
	if ((fp1=fopen(var_file_name,"r"))==NULL)
	{
		AfxMessageBox("\n can not open data file ");
		return;
	}
	fscanf(fp1,"%d%d%d%f%f%f%f%d%d",&ninput ,&noutattr,&ninattr,
		&eta,&alpha,&maxe,&maxep,&nhlayer,&cnt_num);
	for(i=0;i<nhlayer+2;i++)
		fscanf(fp1,"%d",&nunit[i]);
	if ((c=fclose(fp1))!=0)
		AfxMessageBox("\nFile cannot be closed ");
}

void CBPNetDlg::wtread(CString taskname)//读权
{
	int i,j,c;
	CString wt_file_name;
	wt_file_name=taskname;
	wt_file_name=wt_file_name+"_w.dat";
	if ((fp2=fopen(wt_file_name,"r"))==NULL)
	{
		AfxMessageBox("\n cannot open data file");
		return;
	}
	for (i=0; i<nhlayer+1;i++)
	{
		for (j=0;j<(nunit[i]+1)*nunit[i+1];j++)
			fscanf(fp2,"%f",(wtptr[i]+j));
	}
	if ((c=fclose(fp2))!=0)
		AfxMessageBox("\n File can not be closed ");
}

⌨️ 快捷键说明

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