遗传算法简单例题的详解

主函数:

int main()

{

 srand((unsigned)time(NULL));

 

 init();

 GA();

 

 system(“pause”);

 return 0;

}

 

init函数:

void init()    //初始化 建立一个种群

{

  inttmp;

 for(int i=0;i<SIZE;i++)

  {

   tmp=randi(N);

   for(int j=0;j<LEN;j++)

    {

     cur[i].x[j]=tmp%2;   //存储在一定范围内产生随机数被2取余的余数

     tmp=tmp>>1;

    }

  }

 cal_fitness();

}

 

 

randi函数:

int randi(int k)

{

 return (int)(randd()*k+0.5);   //randi()函数生成均匀分布的伪随机整数,范围为imin–imax,如果没指定imin,则默认为1。r =randi(imax,n):生成n*n的矩阵

}

randd函数:

double randd()

{

 return (double)rand()/RAND_MAX; // rand()函数是产生随机数的一个随机函数

}

//计算当前种群中各个个体的适应度

void cal_fitness()

{

  inti,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];  //累加在一定范围内的余数

   d=(double)k/N*3-1;   //d即为在该范围内的一个数值

   cur[i].fitness=d*sin(10*PI*d)+2; //fitness代表该数所求的函数值

   cur[i].fitsum=i>0?(cur[i].fitness+cur[i-1].fitsum):(cur[0].fitness);   //除第0个数之外求该数d所对应的函数值的和前一个的和

  }

}

 

//遗传进化函数

void GA()

{

  intcnt=0;

 double ans;

 while(cnt++<MAXGEN)

  {

   tran();    //进行换代操作

   

//   printf(“%.6lf\n”,max.fitness);

//   printcur();

  }

 ans=cur[0].fitness;

 for(int i=1;i<SIZE;i++) ans=MAX(ans,cur[i].fitness);   // 找到适应度最大的值即为该函数的值

 printf(“%.6lf\n”,ans);

}

 

tran函数:

//换代

void tran()

{

  inti,j,pos;

  //找当前种群最优个体

 max=cur[0];

 for(i=1;i<SIZE-1;i++)

  {

   if(cur[i].fitness>max.fitness) max=cur[i];

  }

 for(int k=0;k<SIZE;k+=2)

  {

   //选择交叉个体

   i=sel();

   j=sel();

   

   //选择交叉位置

   pos=randi(LEN-1);

   

   //交叉

   if(randd()<P_CORSS)   //如果小于交叉概率则进行 如果大于 则进行else

    {

     memcpy(next[k].x,cur[i].x,pos);  //直接把cur【i】.x  拷贝到 next【i】.x

     memcpy(next[k].x+pos,cur[j].x+pos,LEN-pos);  //第pos位置进行复制   从j中第pos起 总共LEN-pos  复制上去 相当于交叉

 

     memcpy(next[k+1].x,cur[j].x,pos);

     memcpy(next[k+1].x+pos,cur[i].x+pos,LEN-pos);   同理 xj分别产生 一个交叉

    }

   else

    {

     memcpy(next[k].x,cur[i].x,LEN);  //直接把复制到下一代 基因型不改变

     memcpy(next[k+1].x,cur[j].x,LEN);

    }

   //变异

   if(randd()<P_MUTATION)   //如果小于则进行变异操作

    {

     pos=randi(LEN-1);       //产生随机数  确定变异的位置在len-1的范围内

     next[k].x[pos]^=next[k].x[pos];   

 

     pos=randi(LEN-1);      //再次进行

     next[k+1].x[pos]^=next[k+1].x[pos];   //在pos位置变为原来的平方

    }

  }

//找下一代的最差个体

 min=next[0],j=0;

 for(i=1;i<SIZE-1;i++)

  {

   if(next[i].fitness<min.fitness) min=next[i],j=i;    //下一代中适应度最低的值

  }

  //用上一代的最优个体替换下一代的最差个体

 next[j]=max;

 

 memcpy(cur,next,sizeof(cur));

  

 

 cal_fitness();    //再次求新一代适应度

}

 

sel函数:

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;    //然后从头到尾找到适应度 大于产生的随机数如果有则返回i

  }

}

 

memcpy函数:   //拷贝函数  调用string 函数即可

 

 

//打印个体适应度和二进制编码

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]);

}

 

/*

用遗传算法求y=x*sin(10*pi*x)+2的最大值  -1=<x<=2

精确到6位小数

pow(2,21)<3*1000000<pow(2,22)

编码的二进制长度为22

*/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <ctime>

#include <math.h>

 

#define N 3000000

#define PI 3.14159265

#define MAX(a,b) ((a)>(b)?(a):(b))

                                  

#define SIZE  50

#define MAXGEN  50

#define P_CORSS 0.75

#define P_MUTATION 0.05

 

#define LEN 22

 

typedef struct node

{

 char x[LEN];   //存储编码

 double fitness,fitsum;   //第一个为最适合  第二个适应度和

}node;  //构建一个结构体来存储

 

node cur[SIZE],next[SIZE],max,min;

    原文作者:遗传算法
    原文地址: https://blog.csdn.net/qq_16184125/article/details/72614595
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞