~~遗传算法最最最最简单的实例~~
这篇文章是上过某算法老师的课后自己闲的无聊写的一个关于遗传算法的简单的实例(由于本人真的很菜,代码写得实在不咋样).本实例旨在求某一函数在某一正整数区间上的返回值的最大值(而且函数返回值还必须是正整数,我是有多菜).具体程序中f(x)=x,寻找的范围是0~31,结果f(x)max=31;
在上代码之前,简单讲讲个人理解.亲子之间以及子代个体之间性状存在相似性,表明性状可以从亲代传递给子代,这种现象称为遗传(heredity)。物竞天择是达尔文进化论的核心,汉语解释是生物互相竞争,能适应生活者被选择存留下来。在生物进化论中的意思是每种生物在繁殖下一代时,都会出现基因的变异。若这种变异是有利于这种生物更好的生活的,那么这种有利变异就会通过环境的筛选,以“适者生存”的方式保留下来。遗传算法就是基于此.在遗传算法中,个体就是一个数据串,评判数据串是否适合题解的是适应度函数,在程序开始时选定某几个随机数据串作为第一代(数据的祖辈),这些数据对应的适应度决定了其被作为父代的概率,再使用随机函数决定父代,由父代进行基因重组,突变,得到子代.
基因重组:比如父代A和父代B,使用随机函数在数据串上某一点截断,两个父代交换各自的一部分,即为基因重组(其实应该叫交叉运算)
基因突变:直接修改某一父代基因上的某一个数据,称为突变
在本实例中,正整数被化为二进制数据串(打字累死了还是贴代码吧QWQ)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define amount 10//每代个体数
#define length 5//个体长度
#define maxtime 1000//最多运行次数
int f(int x){
return x;
}
int main(){
srand(time(NULL));
int arr[amount][length],number[amount],temp[amount][length];
int count=0,refer,maxfit=0,maxrecord,temp1,count2=0,count3,nowmaxfit=0,last;
for(int i=0;i<amount;i++){
for(int j=0;j<=length;j++){
temp[i][j]=0;
arr[i][j]=rand()%2;
if(arr[i][j]!=0&&arr[i][j]!=1)arr[i][j]=1;
}
}//初始化内存
while(count<=maxtime){
count++;//执行一次
int sumfit=0;//总适应度
for(int i=0;i<amount;i++)number[i]=0;
nowmaxfit=0;
for(int i=0;i<amount;i++){
for(int k=length-1;k>=0;k--){
number[i]=number[i]*2+arr[i][k];
}
}//将二进制转换为十进制
for(int i=0;i<amount;i++){
number[i]=f(number[i]);
sumfit+=number[i];
//maxfit=maxfit>number[i]?maxfit:number[i];
if(maxfit<number[i]){
maxfit=number[i];
//maxrecord=i;
}
if(nowmaxfit<number[i]){
nowmaxfit=number[i];
maxrecord=i;
}
}//计算对应适应度
for(int i=0;i<amount;i++){
refer=rand()%sumfit+1;
if(refer>sumfit||refer<0)refer=sumfit;
for(int k=0;k<=amount;k++){
if(refer<0){
for(int j=0;j<length;j++){
temp[i][j]=arr[k-1][j];//temp[i]=arr[k-1]
}
break;
}
else{
refer-=number[k];
}
}
}//物竞天择
for(int i=0;i<amount;i++){
for(int j=0;j<length;j++)arr[i][j]=temp[i][j];
//arr[i]=temp[i];
}
for(int i=0;i<amount;i+=2){
refer=rand()%length;
if(refer>=length||refer<0)refer=length-1;
for(int k=refer+1;k<length;k++){
temp1=arr[i][k];
arr[i][k]=arr[i+1][k];
arr[i+1][k]=temp1;
}
}//基因重组
if(nowmaxfit==maxfit){
count2++;
}
else count2=0;
if(count2>=20){
printf("\n\n\nFinished,max is %d",maxfit);
break;
}
if(nowmaxfit==last){
count3++;
}
else count3=0;
last=nowmaxfit;
if(count3>=10){
arr[rand()%amount][rand()%(length+1)]=rand()%2;
}//突变
printf("\n\nthis is the %d time,the maxfit is %d,nowmaxfit=%d\n",count,maxfit,nowmaxfit);
printf("Menbers are:\n");
for(int i=0;i<amount;i++){
for(int j=0;j<length;j++){
printf("%d ",arr[i][j]);
//if(arr[i][j]!=0&&arr[i][j]!=1)arr[i][j]=1;
}
printf("\n");
}
}
return 0;
}
这个代码里面显示了各代情况,我使用判断的结束条件是当保存的适应度最大值maxfit与当前一代的适应度最大值nowmaxfit连续20次相等时结束循环.
PS:写代码过程中,我不知道还有突变这种东西(老师只讲个大概咋回事),导致运行过程中有每代中全是一样的个体(很烦TAT)后来修改的措施是在nowmaxfit连续10代相同后,对随机某个个体进行随机突变,程序就可以运行了.
(本人还是小白,求大神放过QWQ)
最后贴上大神镇楼~