简易遗传算法(浮点数编码)

来源:互联网 发布:scrollfix.js 编辑:程序博客网 时间:2024/04/30 10:23

#include<stdio.h>#include<stdlib.h> #include<math.h>#include<time.h> #define M 80//种群数量#define XMIN -1//下限#define XMAX 2//上限#define PI 3.1415926#define PC 0.8//交叉概率#define PM 0.18//变异概率#define PA 0.01//交叉因子struct Node{double Pmember;double Myfitness;//Myfitness是适应度double Myfitsum;//Myfitsum是适应度占总体适应度的百分比,然后从第一个个体往后累加,主要用于选择操作double Myfitave;}Nownode[M],Nextnode[M];//本代群体和下一代群体int nodeindex[M];//交叉时随机配对,存放配对的群体下标int T=0;double fx(double x)//根据x计算fx{double y;y=x*sin(10*PI*x)+2;//y=100-(x-5)*(x-5);return y;}int calfitness()//计算适应度值{int i;double minfitness,maxfitness,avefitness=0;double C=1.7,a,b;double temp;minfitness=Nownode[0].Myfitness=fx(Nownode[0].Pmember);maxfitness=minfitness;avefitness=maxfitness;for(i=1;i<M;i++){Nownode[i].Myfitness=fx(Nownode[i].Pmember);avefitness+=Nownode[i].Myfitness;if(minfitness>Nownode[i].Myfitness){minfitness=Nownode[i].Myfitness;}if(maxfitness<Nownode[i].Myfitness){maxfitness=Nownode[i].Myfitness;}}if(minfitness<0)//如果有负的适应度值,就把所以的适应度都加上一个数,使适应度全都为正数{temp=minfitness;Nownode[0].Myfitness+=-temp;avefitness=Nownode[0].Myfitness;maxfitness=Nownode[0].Myfitness;minfitness=Nownode[0].Myfitness;for(i=1;i<M;i++){Nownode[i].Myfitness+=-temp;avefitness+=Nownode[i].Myfitness;if(minfitness>Nownode[i].Myfitness){minfitness=Nownode[i].Myfitness;}if(maxfitness<Nownode[i].Myfitness){maxfitness=Nownode[i].Myfitness;}}}//适应度线性变换avefitness=avefitness/M;//计算平均适应度if(minfitness>(C*avefitness-maxfitness)/(C-1)){a=(C-1)*avefitness/(maxfitness-avefitness);b=(maxfitness-C*avefitness)*avefitness/(maxfitness-avefitness);}else{a=avefitness/(avefitness-minfitness);b=minfitness*avefitness/(avefitness-minfitness);}for(i=0;i<M;i++){Nownode[i].Myfitness=a*Nownode[i].Myfitness+b;}Nownode[0].Myfitsum=Nownode[0].Myfitness;for(i=1;i<M;i++){Nownode[i].Myfitsum=Nownode[i].Myfitness+Nownode[i-1].Myfitsum;//每一个Myfitsum都是自己的适应度加上前一个的Myfitsum}for(i=0;i<M;i++){Nownode[i].Myfitave=Nownode[M-1].Myfitsum/M;}for(i=0;i<M;i++){Nownode[i].Myfitsum=Nownode[i].Myfitsum/Nownode[M-1].Myfitsum;//每一个Myfitsum除以所有适应度之和,使Myfitsum为0~1之间}return 0;}double randn()//产生XMIN到XMAX之间的随机数{return XMIN+1.0*rand()/RAND_MAX*(XMAX-XMIN);}int initpopulation()//初始化种群{int i;for(i=0;i<M;i++){Nownode[i].Pmember=randn();}calfitness();//计算适应度return 0;}int assignment(struct Node *node1,struct Node *node2)//把node2的值赋值给node1{node1->Pmember=node2->Pmember;node1->Myfitness=node2->Myfitness;node1->Myfitsum=node2->Myfitsum;node1->Myfitave=node2->Myfitave;return 0;}int copypopulation()//复制操作{int i,num=0;double temp;while(num<M){temp=1.0*rand()/RAND_MAX;for(i=1;i<M;i++){if(temp<=Nownode[0].Myfitsum){assignment(&Nextnode[num++],&Nownode[0]);//把第一个个体复制到下一代break;}if(temp>=Nownode[i-1].Myfitsum&&temp<=Nownode[i].Myfitsum)//把第i个个体复制到下一代{assignment(&Nextnode[num++],&Nownode[i]);break;}}}for(i=0;i<M;i++){assignment(&Nownode[i],&Nextnode[i]);//更新本代个体}calfitness();//计算适应度return 0;}int isrepeat(int temp,int n)//产生随机下标判断是否重复{int i;for(i=0;i<n;i++){if(nodeindex[i]==temp)return 1;}return 0;}int crossover(){int i,temp;double temp_pc;for(i=0;i<M;i++)//产生交叉点的下标{do {temp=rand()%M;} while(isrepeat(temp,i));nodeindex[i]=temp;}for(i=0;i<M;i=i+2){temp_pc=1.0*rand()/RAND_MAX;//如果满足交叉的条件,就开始交叉if(temp_pc<=PC){Nownode[nodeindex[i]].Pmember=PA*Nownode[nodeindex[i+1]].Pmember+(1-PA)*Nownode[nodeindex[i]].Pmember;Nownode[nodeindex[i+1]].Pmember=PA*Nownode[nodeindex[i]].Pmember+(1-PA)*Nownode[nodeindex[i+1]].Pmember;}}calfitness();//计算适应度return 0;}int mutation()//变异操作{int i,temp;double k=0.8,temp_pm;for(i=0;i<M;i++){temp_pm=1.0*rand()/RAND_MAX;if(temp_pm<=PM)//如果满足变异条件,就开始变异{temp=rand()%2;if(temp==0){Nownode[i].Pmember=Nownode[i].Pmember+k*(XMAX-Nownode[i].Pmember)*1.0*rand()/RAND_MAX;}else{Nownode[i].Pmember=Nownode[i].Pmember-k*(Nownode[i].Pmember-XMIN)*1.0*rand()/RAND_MAX;}}}calfitness();//计算适应度return 0;}int findmaxfit()//找到适应度最大的个体{int i,index=0;double temp=0;for(i=0;i<M;i++){if(temp<Nownode[i].Myfitness){index=i;temp=Nownode[i].Myfitness;}}return index;}int main(){int i=0,index;int num=0,num1=0,num2=0;srand(time(NULL));while(num++<1000){T=0;initpopulation();while(T++<200){copypopulation();crossover();mutation();}index=findmaxfit();if(fabs(Nownode[index].Pmember-1.85)<=0.1){num1++;}else{num2++;}}printf("正确的次数有%d次\n",num1);printf("错误的次数有%d次\n",num2);return 0;}








0 0
原创粉丝点击