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

📄 bp1.2.cpp

📁 完成BP人工神经网络算法的学习
💻 CPP
字号:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>  

#define Learn 0.3       //学习率
#define err 0.00001       //最大误差

typedef struct LNode    //存储实例和期望值
{
	float x1;
    float x2;
	float y1;
	float y2;
	struct LNode *next;
}LNode, *LinkList;

void readexample(LinkList *L);                   //从文件读取实例
float MAXE(float E[],int e);                     //求最大误差
void Print_L(LinkList *L);                       //输出实例
void See_emax(float EMAX[]);                     //查看某次学习最大误差
void initiarray(float w1[][4],float w2[][4],float w3[][3]);    //随机初始权矩阵
void initiarray2(float w1[][4],float w2[][4],float w3[][3]);   //显示初始权矩阵
void printarray(float w1[][4],float w2[][4],float w3[][3]);    //输出权矩阵
void learn(LinkList L, float w1[][4],float w2[][4],float w3[][3],float EMAX[]);      //学习实例
void assess(float w1[][4],float w2[][4],float w3[][3]);                 //模糊评判

void main()
{
	
	LinkList L= (LinkList)malloc(sizeof(LNode));
	float w1[3][4],w2[4][4],w3[4][3],EMAX[200000];

	readexample(&L);
//	Print_L(&L);

//  initiarray(w1,w2,w3);         //随机初始权矩阵 
    initiarray2(w1,w2,w3);        //显示初始权矩阵
//	printarray(w1,w2,w3);

//	printf("---------------\n");
		
   learn(L, w1,w2,w3,EMAX);

   assess(w1,w2,w3);

   See_emax(EMAX);

   printarray(w1,w2,w3);


}


void learn(LinkList L, float w1[][4],float w2[][4],float w3[][3],float EMAX[])
{
	int i,j,e;
	long t=1;
	unsigned long a=0,count=0;
	float MAX=1.0;
	float E[41],E2[4],E3[4],E4[3],o1[3],o2[4],o3[4],o4[3];	
	LinkList p;

	while(MAX>err)
	{
		e=1;
		p=L->next;		

		while(p)
		{
		    o1[1]=p->x1;
			o1[2]=p->x2;

			for(i=1;i<=3;i++)
				o2[i]=1/(1+exp(-(w1[1][i]*o1[1]+w1[2][i]*o1[2])));   //第2层输出

            for(i=1;i<=3;i++)
				o3[i]=1/(1+exp(-(w2[1][i]*o2[1]+w2[2][i]*o2[2]+w2[3][i]*o2[3])));    //第3层输出

			for(i=1;i<=2;i++)
				o4[i]=1/(1+exp(-(w3[1][i]*o3[1]+w3[2][i]*o3[2]+w3[3][i]*o3[3])));     //第4层输出				

			E4[1]=o4[1]-p->y1;           //计算每次输出误差
			E[e++]=fabs(E4[1]);          //存放每次误差
		    E4[2]=o4[2]-p->y2;
			E[e++]=fabs(E4[2]);

			for(i=1;i<=3;i++)
				E3[i]=o3[i]*(1-o3[i])*(w3[i][1]*E4[1]+w3[i][2]*E4[2]);     //第3层误差
			

            for(i=1;i<=3;i++)
				E2[i]=o2[i]*(1-o2[i])*(w2[i][1]*E3[1]+w2[i][2]*E3[2]+w2[i][3]*E3[3]);     //第2层误差
      

            for(i=1;i<=3;i++)   
				for(j=1;j<=2;j++)
					w3[i][j]=w3[i][j]-Learn*E4[j]*o3[i];                 //修改W3矩阵

			for(i=1;i<=3;i++)
				for(j=1;j<=3;j++)
					w2[i][j]=w2[i][j]-Learn*E3[j]*o2[i];                //修改W2矩阵

			for(i=1;i<=2;i++)
				for(j=1;j<=3;j++)
					w1[i][j]=w1[i][j]-Learn*E2[j]*o1[i];	            //修改W1矩阵

			p=p->next;

		}  //while(p)

        count++;                      // 学习遍数+1
	


		MAX=MAXE(E,e);                //计算最大误差

        EMAX[t++]=MAX;

		
	}//while(MAX>err) 

       
		printf("学习遍数count=%ld\n",count); 	


}




void readexample(LinkList *L)                 //从指定文件读取实例
{
		FILE *fp;
		LinkList p=*L,r;

		if((fp=fopen("c:\\bp1.txt","r"))==NULL)
		{
		     printf("Open file error!\n");
		     exit(0);
		}

		while(!feof(fp))
		{
			r=(LinkList)malloc(sizeof(LNode));
			r->next=NULL;
			p->next=r;
			fscanf(fp,"%f%f%f%f",&r->x1,&r->x2,&r->y1,&r->y2);

			p=r;
		}

		fclose(fp);
}


void initiarray(float w1[][4],float w2[][4],float w3[][3])             //随机初始权矩阵 
{
	int i,j;
	for(i=1;i<=2;i++)
		for(j=1;j<=3;j++)
			w1[i][j]=rand()%100*1.0/100;

	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++)
			w2[i][j]=rand()%100*1.0/100;

	for(i=1;i<=3;i++)
		for(j=1;j<=2;j++)
			w3[i][j]=rand()%100*1.0/100;
}


void initiarray2(float w1[][4],float w2[][4],float w3[][3])   //显示初始权矩阵
{
	FILE *fp;
	int i,j;
    
	if((fp=fopen("c:\\bp11.txt","r"))==NULL)
	{
		printf("Open file error!\n");
		exit(0);
	}

	for(i=1;i<=2;i++)
		for(j=1;j<=3;j++)
			fscanf(fp,"%f",&w1[i][j]);

	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++)
			fscanf(fp,"%f",&w2[i][j]);

	for(i=1;i<=3;i++)
		for(j=1;j<=2;j++)
			fscanf(fp,"%f",&w3[i][j]);

		fclose(fp);
}



float MAXE(float E[21],int e)              //返回最大误差值
{
	float max=0;
	int i;

	for(i=1;i<e;i++)
		if(max<E[i])
			max=E[i];

		return max;
}



			
void printarray(float w1[][4],float w2[][4],float w3[][3])       //输出权矩阵
{
    int i,j;

	printf("最后权矩阵如下:\n");

	for(i=1;i<=2;i++)
		for(j=1;j<=3;j++)
			printf("w1[%d][%d]=%f  ",i,j,w1[i][j]);
		printf("\n");

	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++)
				printf("w2[%d][%d]=%f  ",i,j,w2[i][j]);
			printf("\n");

	for(i=1;i<=3;i++)
		for(j=1;j<=2;j++)
				printf("w3[%d][%d]=%f  ",i,j,w3[i][j]);
			printf("\n");
}


void Print_L(LinkList *L)                 //输出读取的实例
{
	LinkList p=(*L)->next;

	if(!p)	
		printf("链表创建为空");	        

	while(p)
	{
		printf("%f  %f  %f  %f\n",p->x1,p->x2,p->y1,p->y2);
		p=p->next;
	}
	printf("\n");
}


void See_emax(float EMAX[])
{
	long i;
	printf("输入学习的遍数:");
	scanf("%d",&i);	
	printf("EMAX[%ld]=%f \n",i,EMAX[i]);
}


void assess(float w1[][4],float w2[][4],float w3[][3])
{
	int i;
	float o1[3],o2[4],o3[4],o4[3],b[3];

	printf("输入实例x1,x2:");
	scanf("%f%f",&o1[1],&o1[2]);

    for(i=1;i<=3;i++)
		o2[i]=1/(1+exp(-(w1[1][i]*o1[1]+w1[2][i]*o1[2])));   //第2层输出

    for(i=1;i<=3;i++)
	    o3[i]=1/(1+exp(-(w2[1][i]*o2[1]+w2[2][i]*o2[2]+w2[3][i]*o2[3])));    //第3层输出

	for(i=1;i<=2;i++)
		o4[i]=1/(1+exp(-(w3[1][i]*o3[1]+w3[2][i]*o3[2]+w3[3][i]*o3[3])));     //第4层输出

	printf("y1=%f,y2=%f\n",o4[1],o4[2]);

	printf("对象X的评价:");

	for(i=1;i<=2;i++)
	{
		b[i]=(float)((int)(o4[i]*10+0.5))/10.0;

	    switch ((int)(10*b[i]))
		{
	     case 10:  printf("“肯定是”");   break;
	 	 case 9 :  printf("“几乎是”");   break;
		 case 8 :  printf("“极是”");     break;
		 case 7 :  printf("“很是”");     break;
         case 6 :  printf("“相当是”");   break;
         case 5 :  printf("“差不多是”"); break;
		 case 4 :  printf("“比较像是”"); break;
		 case 3 :  printf("“有些像是”"); break;
		 case 2 :  printf("“有点像是”"); break;
		 case 1 :  printf("“稍稍像是”"); break;
		 case 0 :  printf("“肯定不是”"); break;
		 default:  break;
		
	   }

	   if(i==1)    printf("属于R1类,");
	   if(i==2)    printf("属于R2类。");
	 }

	printf("\n");


}



⌨️ 快捷键说明

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