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

📄 main.c

📁 神经网络和遗传算法相结合的算法
💻 C
字号:
#include "DSP28_Device.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "time.h"
#include "math.h"


//宏定义控制参数
#define N   21 //学习样本个数
#define IN  1 //输入层神经元数目
#define HN  4 //隐层神经元数目
#define ON  1 //输出层神经元数目
#define POPSIZE  10  //定义种群的大小
#define NVARS  (IN*HN+HN*ON+HN+ON)  //定义参数的个数
#define MaxIter 105000//最大迭代次数
//#define Z 1  //保存旧权值


//全局变量定义
float P[IN]; //单个样本输入数据
float T[ON]; //单个样本教师数据
float W[HN][IN]; //输入层至隐层权值,初始化时使用
float V[ON][HN]; //隐层至输出层权值,初始化时使用
float Ww[HN][IN]; //输入层至隐层权值,网络训练时使用
float Vv[ON][HN]; //隐层至输出层权值,网络训练时使用
float X[HN]; //隐层的净输入
float Y[ON]; //输出层的输入
float H[HN]; //隐层的输出
float O[ON]; //输出层的输出
float YU_HN[HN]; //隐层的阈值,初始化时使用
float YU_ON[ON]; //输出层的阈值,初始化时使用
float YU_H[HN]; //隐层的阈值,网络训练时使用
float YU_O[ON]; //输出层的阈值,网络训练时使用
float err_m[N]; //第m个样本的总误差
float err_tol;//允许误差
float sqr_err=0;//每个样本的平方误差计算都是从0开始的
int   LocalConFlg;
int   ConvCount=0;
int   ConvergeFlg=0;
int   pop;
int   newp;
int   flag_1=0;
Uint32   CurrIter_total;
int   CurrIter_single;
float ETA;                 // Learning rate  学习速率
float ALPHA;               // Momentum       动量项,加快学习速度

//float a; //输出层至隐层的学习效率
//float b; //隐层至输入层学习效率
//float alpha;//动量因子
int flag=0;//标志位,用于标识是否进行总体样本误差的权值调整
float out[N][ON];//网络输出
int   CurrPat=-1; //当前训练样本
int   location[POPSIZE+1];     //排序后的个体的位置
int   gen;      //当前代数
//static float maxgen;  //最大代数
int   change=0; //适应性没有改进的代数
int   v=0,u=0,uu=0,vv=0;
float pc1=0.9,pc2=0.6;//pm1=0.1,pm2=0.001;
float pmt1,pmt2;
float error;//评估函数
float e_err[HN];
float e_err_total[HN];//隐层至输入层的一般化误差子程序
float d_err[ON];
float d_err_total[ON]; //输出层至隐层的一般化误差子程序
float old_sum_err=0.0,sum_err=0.0;
//定义一个放学习样本的结构
struct Study{
float input[IN]; //网络训练的输入数据	
float teach[ON]; //网络训练的教师数据
}Study_Data[N];

//定义用来保存每次计算的权值和阈值的结构
struct Old
 {
    float old_W[HN][IN];  //保存HN-IN旧权!
    float old_V[ON][HN];  //保存ON-HN旧权!
    float old_YU_HN[HN]; 
    float old_YU_ON[ON];
 }Old_WV;

struct  individual   //定义基因,种群中的一个个体
 {
	float chrom[NVARS]; //定义需整定的网络参数数组,即相关的权值和阈值组成的数组
	float lsquare;      //个体的评价度,存放的是评价函数的返回值,即误差平方和的大小
	float r;            //个体的相关系数
	float fitness;      //相关适应度
 };

struct individual newpop[POPSIZE+1];  //新种群
struct individual oldpop[POPSIZE+1];  //老种群
struct Study Study_Data[N];//学习样本
struct Old Old_WV;


// 训练数据
struct Study Study_Data[21]={{0.000,0.50000},{0.31416,0.65451},{0.62832,0.79389},
{0.94248,0.90451},{1.25664,0.97553},{1.57080,1.00000},{1.88496,0.97553},
{2.19911,0.90451},{2.51327,0.79389},{2.82743,0.65451},{3.14159,0.50000},
{3.45575,0.34549},{3.76991,0.20611},{4.08407,0.09549},{4.39823,0.02447},
{4.71239,0.00000},{5.02655,0.02447},{5.34071,0.09549},{5.65487,0.20611},
{5.96903,0.34549},{6.28319,0.50000}};

float input[41]={0.0,0.025,0.05,0.075,0.1,0.125,0.15,0.175,0.2,0.225,0.25,0.275,0.3,0.325,0.35,0.375,0.4,0.425,0.45,0.475,0.5,0.525,0.55,0.575,0.6,0.625,0.65,0.675,0.7,0.725,0.75,0.775,0.8,0.825,0.85,0.875,0.9,0.925,0.95,0.975,1.0};
float output[41];
/*{0.1257,0.2513,0.3770,0.5027,0.6283,0.7540,0.8796,1.0053,1.1310,1.2566,
				1.3823,1.5080,1.6336,1.7593,1.8850,2.0106,2.1363,2.2619,2.3876,2.5133,
				 2.6389,2.7646,2.8903,3.0159,3.1416,3.2673,3.3929,3.5186,3.6442,3.7699,
				 3.8956,4.0212,4.1469,4.2726,4.3982,4.5239,4.6496,4.7752,4.9009,5.0265,
				 5.1522,5.2779,5.4035,5.5292,5.6549,5.7805,5.9062,6.0319,6.1575,6.2832};*/



//函数声明
int    saveWV(float *chrom0);
void   quick_sort(float *item,int left,int right,int *locat);
void   quick_sort_all(float *item,int left,int right,int *locat);
void   quick_sort_length(float *item,int left,int right,int *locat);
void   normalfitness(struct individual *pop);
int    initial(void);
void   initpop(void);
void   initialize(void);
int    Unitary_Date(void);
int    GetInputs(void);
int    H_I_O(void);
int    O_I_O(void);
int    Err_gen(void);
void   AdaptWeights(void);
float  Err_Sum();
float  evaluate(float *prms);
int    select(struct individual *pop);
float  mutate(int i);
void   xover(float *parent1,float *parent2,float *child1,float *child2);
void   recombine(void);
int    rdfloat(int i);
float  rdft();
int    rnd(int a,int b);



//产生随机整数0~i之间
int rdfloat(int nn)
{
 int mm;
 mm=rand()%(int)(nn);
 return mm;
}
//产生随机实数0~1之间
float rdft()
{
 float mm;
 mm=(float)rdfloat(16384)/(16383.0);
 return mm;
}
//产生a~b之间的随机整数
int rnd(int a,int b)
{
 int mm;
 mm=rdfloat((int)(b)-(int)(a)+1)+(int)(a);
 return mm;
 }

//保存旧权值的函数
int saveWV(float *chrom0)  //m代表计算次数,即第m次运算后得到的权值和阈值
{
	int k,i,ii,j,jj,l,ll;
	k=0;
	for(i=0;i<HN;i++)
	{
		for(j=0;j<IN;j++)
		{
			Old_WV.old_W[i][j] = chrom0[k++];
		}
	}
	
	for(ii=0;ii<ON;ii++)
	{
		for(jj=0;jj<HN;jj++)
		{
			Old_WV.old_V[ii][jj] =chrom0[k++];
		}
	}
	
	for(l=0;l<HN;l++)
	{
		Old_WV.old_YU_HN[l]=chrom0[k++];
	}
    for(ll=0;ll<ON;ll++)
	{
		Old_WV.old_YU_ON[ll]=chrom0[k++];
	}
	return 1;
}




//用于确定数组选择区域函数,通过快速排序法实现,(二分法排序)

//locat数组中保存排序后的各个元素在原来数组中的位置,即原先的下标值
void quick_sort(float *item,int left,int right,int *locat) //<号升序>号降序 
      //item:需排序的数组,left:数组的下标下界, 
	  //right:数组的下标上界,locat:数组中各元素在原数组中的位置
      //求最大值则用升序,求最小值用降序
{
    float fa,fb;
    int i,j,k;
    //KickDog();
	i=left;j=right;
	fa=item[(left+right)/2];

	do{

		while((item[i]>fa)&&(i<right))i++;       //降序排列 
		while((fa>item[j])&&(j>left))j--;         


		if(i<=j)
		{
			fb=item[i];
			item[i]=item[j];
			item[j]=fb;

			k=locat[i];
			locat[i]=locat[j];
			locat[j]=k;

			i++;j--;
		}

	}while(i<=j);
	if(left<j) quick_sort(&item[0],left,j,&locat[0]);
	if(i<right)quick_sort(&item[0],i,right,&locat[0]);
}


void quick_sort_all(float *item,int left,int right,int *locat) //<号升序>号降序 
      //item:需排序的数组,left:数组的下标下界, 
	  //right:数组的下标上界,locat:数组中各元素在原数组中的位置
      //求最大值则用升序,求最小值用降序
{
    float fa,fb;
    int i,j,k;
	
	i=left;j=right;
	fa=item[(left+right)/2];

	do{

		while((item[i]<fa)&&(i<right))i++;   //升序排列
		while((fa<item[j])&&(j>left))j--;

		if(i<=j)
		{
			fb=item[i];
			item[i]=item[j];
			item[j]=fb;

			k=locat[i];
			locat[i]=locat[j];
			locat[j]=k;

			i++;j--;
				
		}

	}while(i<=j);
	if(left<j) quick_sort_all(&item[0],left,j,&locat[0]);
	if(i<right)quick_sort_all(&item[0],i,right,&locat[0]);
}


void quick_sort_length(float *item,int left,int right,int *locat) //<号升序>号降序 
      //item:需排序的数组,left:数组的下标下界, 
	  //right:数组的下标上界,locat:数组中各元素在原数组中的位置
      //求最大值则用升序,求最小值用降序
{
    float fa,fb;
    int i,j,k;

	i=left;j=right;
	fa=item[(left+right)/2];

	do{

		while((item[i]>fa)&&(i<right))i++;   //降序排列
		while((fa>item[j])&&(j>left))j--;

		if(i<=j)
		{
			fb=item[i];
			item[i]=item[j];
			item[j]=fb;
 
			k=locat[i];
			locat[i]=locat[j];
			locat[j]=k;

			i++;j--;
		}

	}while(i<=j);
	if(left<j) quick_sort_length(&item[0],left,j,&locat[0]);
	if(i<right)quick_sort_length(&item[0],i,right,&locat[0]);
}


void normalfitness(struct individual *pop)  //参数是种群数组newpop[]等
{
	float fit[POPSIZE];
	int i;
	float fitsum,fitave;
	fitsum=0.0;

	for(i=0;i<POPSIZE;i++)
	{
		fit[i]=pop[i].lsquare;  //个体的适应性 
		location[i]=i;
		fitsum+=fit[i];
		}

	fitave=fitsum/POPSIZE;

	quick_sort(&fit[0],0,POPSIZE-1,&location[0]);   //降序排列

	for(i=0;i<POPSIZE;i++)
	{
		pop[location[i]].fitness=2*(i+1);   //重新计算适应度,计算后原先误差大的将变小
	                                       //因初始适应度是用评价函数的返回值表示的,而评价函数返回的是误差,
	                                       //故原先氖视Χ却蟮谋硎臼导饰蟛畲螅

⌨️ 快捷键说明

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