遗传算法C语言源码
来源:互联网 发布:欧莱雅润发精油 知乎 编辑:程序博客网 时间:2024/06/05 03:57
遗传算法是上学时曾经研究过的算法,它是一种基于基因遗传思想的快速搜索遍历算法。简单理解,它就是比一般的盲搜索和其他的一些搜索快的算法。其主要目的就是为了能快速准确搜索所求的值,用于求解一些复杂的数值应用,以及一些实时性要求高的算法应用中。以下是以前练习过的代码,欢迎有需要的同学学习交流。
include <stdio.h>include <string.h>include <stdlib.h>include <ctime>include <math.h>define N 30000000000define PI 3.14159265define MIN_(a,b) ((a)>(b)?(b):(a))//定义求最小值函数MIN_(a,b) define SIZE 50define MAXGEN 50define P_CORSS 0.75define P_MUTATION 0.05define LEN 22typedef struct node//定义结构体,表示染色体,x是染色体二进制编码,fitness是该染色体的适应值,fitsum是当前所有染色体的适应值的总和{ char x[LEN]; double fitness,fitsum;}node;node cur[SIZE],next[SIZE],max,min;//定义结构体数组,有当前染色体种群,下一代染色体种群,以及最优和最差染色体。double randd(){ return (double)rand()/RAND_MAX;//产生0-1之间随机数, RAND_MAX其值至少为32767,rand()在0-MAX之间}int randi(int k){ return (int)(randd()*k+0.5);//返回接近k大小的随机值}//计算当前种群中各个个体的适应度 void cal_fitness(){ int i,j,k; double d; for(i=0;i<SIZE;i++) { k=0; for(j=LEN-1;j>=0;j--) k=(k<<1)+cur[i].x[j];;//该循环用于将染色体二进制数转成十进制,<<是左移运算,x[j]是染色体i的第j位 d=(double)k/N*100-50;//用上面的k产生一个浮点数d,作为函数自变量x的值 cur[i].fitness=d+10*sin(5*d)+7*cos(4*d); //计算每个染色体的适应值 //////// //函数y= x+10*sin(5*x)+7*cos(4*x)////////////// cur[i].fitsum=i>0?(cur[i].fitness+cur[i-1].fitsum):(cur[0].fitness);//计算所有适应值的总和,里面有迭代过程,就是若i=3,则cur[3].fitsum=cur[3].fitsum+cur[2].fitsum+cur[1].fitsum+cur[0].fitsum. }}void init()//初始化染色体种群,共SIZE个,每个都是二进制LEN长度的串{ int tmp; for(int i=0;i<SIZE;i++) { tmp=randi(N);//用randi函数产生一个大概N那么大的随机数 for(int j=0;j<LEN;j++) { cur[i].x[j]=tmp%2;//用temp对2取余,初始化每个染色体的每个位,共LEN位;一个数不是奇数就是偶数,对2取余得0或1,从而产生像001001010...11010001这样的串 tmp=tmp>>1;//右移tmp,就是将temp缩小,使tmp值变化 } } cal_fitness();//计算当前种群各个个体的适应度 }int sel()//选择种群中某个染色体{ double p=randd(); double sum=cur[SIZE-1].fitsum;//全部染色体的适应值总和 for(int i=0;i<SIZE;i++) { if(cur[i].fitsum/sum>p) return i;//如果当前适应总值/全部总值大于随机数p,也就是当前适应总值不为0,不太差时,返回这个i值,循环停止 }}//换代 void tran(){ int i,j,pos; //找当前种群最优个体 max=cur[0]; for(i=1;i<SIZE-1;i++) { if(cur[i].fitness>max.fitness) max=cur[i];//记录种群中的最优染色体为max } for(int k=0;k<SIZE;k+=2) { //选择交叉个体 i=sel();//用sel函数挑选一个个体,染色体号为i j=sel();//同上,再选择个个体,号为j //选择交叉位置 pos=randi(LEN-1);//随机产生个LEN-1左右的数pos,如18,19,21等 //交叉 if(randd()<P_CORSS)//如果randd()产生的随机数(在0-1之间)小于设定的交叉率P_CORSS { memcpy(next[k].x,cur[i].x,pos);//提取染色体i的前pos位赋给下一代种群next的第k个染色体.——函数memcpy(&a,&b,n)用于从&b的位置开始数n个长度的数据拷贝赋给&a; memcpy(next[k].x+pos,cur[j].x+pos,LEN-pos);//提取染色体j的 后面LEN-pos位赋给next的第k个染色体,结合上面,从而拼成一个新的染色体 memcpy(next[k+1].x,cur[j].x,pos);//同样的方式给next的第k+1染色体赋值,这回换过来生成这个值,即提取j的前pos位数据 + i的后LEN-pos位数据 memcpy(next[k+1].x+pos,cur[i].x+pos,LEN-pos); } else//否则不交叉, { memcpy(next[k].x,cur[i].x,LEN); memcpy(next[k+1].x,cur[j].x,LEN); } //变异 if(randd()<P_MUTATION)//如果一随机数小于设定的变异率P_MUTATION,则执行变异操作 { pos=randi(LEN-1);//仍然是从中间找个位置,执行变异 next[k].x[pos]^=next[k].x[pos];// ^=按位异或后赋值函数,相同为0不同为1,此处是将第pos位上的值(不论是0或1)定为0 pos=randi(LEN-1); next[k+1].x[pos]^=next[k+1].x[pos];//同样将下一代next的第k+1个染色体的第pos位也变为0;??最好应该是0变1,1变0...,但这样也行,进化稍慢点 } } //找下一代的最差个体 min=next[0],j=0; for(i=1;i<SIZE-1;i++) { if(next[i].fitness<min.fitness) min=next[i],j=i;//用j记录最差染色体号 } //用上一代的最优个体替换下一代的最差个体 next[j]=max; memcpy(cur,next,sizeof(cur));//把整个改良过的(经过交叉,变异,替换等操作的)next代的值赋给当前种群cur,供下一次循环优化 cal_fitness();}//打印个体适应度和二进制编码 void print(node tmp){ printf("%.6lf",tmp.fitness); for(int i=0;i<LEN;i++) printf(" %d",tmp.x[i]); printf("\n");}//打印种群void printcur(){ for(int i=0;i<SIZE;i++) print(cur[i]);} void GA(){ int cnt=0; double ans; while(cnt++<MAXGEN)//当计数值cnt小于设定的最大进化次数MAXGEN,执行换代操作 { tran(); } ans=cur[0].fitness; for(int i=1;i<SIZE;i++) ans=MIN_(ans,cur[i].fitness);//找出函数最小值,打印输出(应设定的是求函数最小值) printf("%.6lf\n",ans);}int main(){ srand((unsigned)time(NULL));//初始化随机数种子产生器,为使程序中每次的rand()函数产生的随机数不一样 init();//初始化种群 GA();//遗传换代操作 system("pause"); //输出结果在屏幕,而不是一闪而过 return 0;}
0 0
- 遗传算法C语言源码
- 遗传算法的C语言实现(二)
- 遗传算法入门,源码
- 遗传算法_C语言
- R语言遗传算法
- 原材料配送问题的遗传算法实现(C语言)
- 遗传算法(GA)的C语言实现
- C语言编写遗传算法解决TSP旅行商问题
- 遗传算法(C#)
- 遗传算法:go语言实现
- DES算法C语言源码
- 遗传算法的C源程序
- 遗传算法的c程序
- 【搞搞算法】多目标遗传算法NSGA-II的C语言代码使用手册
- [转载]遗传算法改进的模糊C-均值聚类MATLAB源码
- 遗传算法的一个例子(C/C++)
- 转载R语言实现遗传算法
- Go语言如何实现遗传算法
- URI(统一资源标识符)和URL(统一资源定位符)的区别
- 华为机试专辑【1-5题】
- Expedition poj 2431
- 消息推送入门学习
- cache源码分析三 evacuate机制的实现
- 遗传算法C语言源码
- 漫谈程序员系列:让程序员蛋疼的那些事儿
- mybatis的mapper映射文件的加载(resource方式,class方式,以及包扫描)
- 文章标题 2017春电子竞赛FPGA基本任务训练——HDL Verilog实验报告
- Matchsticks to Square
- maven的几种依赖关系
- 在MacOS上使用终端操作数据库
- cache源码分析四 初始化与元数据同步
- 如何将Android Studio的工程导入到eclipse中