📄 main.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 + -