简易遗传算法(浮点数编码)
2015-06-28 13:03
411 查看
#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; }
相关文章推荐
- ubuntu下使用vi编辑文件时 上下左右键 输出ABCD的问题
- android单元测试 activity跳转 以及 input 输入后 测试
- Spring MVC 数据验证——validate编码方式
- Mac OS 10.10.3 下 AndroidStudio单元测试
- 命令模式
- hibernate关联对象的增删改查------增
- hdu 5101 Select
- atitit. 管理哲学 大毁灭--- 如何防止企业的自我毁灭
- hibernate关联对象的增删改查------增
- atitit. 管理哲学 大毁灭--- 如何防止企业的自我毁灭
- java链接mysql数据库
- CFile 与 CStdioFile的区别
- jdk的安装
- 何为码农?
- linux设备驱动程序之并发和竞态(一)
- 工具类网站集合
- CSDN第一天——简单的登录注册及针对不同用户显示不同界面
- PHP命令行下的世界
- HTML 笔记
- 关于android sqlite数据库使用的几点心得