遗传算法 二进制编码方式

转自:
http://www.cnblogs.com/algorithms/archive/2012/05/19/2509322.html

 /*
  用遗传算法求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;

  double randd()
  {
    return (double)rand()/RAND_MAX;
  }
  int randi(int k)
  {
    return (int)(randd()*k+0.5);
  }

  //计算当前种群中各个个体的适应度 
  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];
      d=(double)k/N*3-1;
      cur[i].fitness=d*sin(10*PI*d)+2;
      cur[i].fitsum=i>0?(cur[i].fitness+cur[i-1].fitsum):(cur[0].fitness);
    }
  }

  void init()
  {
    int tmp;
    for(int i=0;i<SIZE;i++)
    {
      tmp=randi(N);
      for(int j=0;j<LEN;j++)
      {
       cur[i].x[j]=tmp%2;
        tmp=tmp>>1;
      }
    }
    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;
    }
  }

  //换代 
  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];
    }
    for(int k=0;k<SIZE;k+=2)
    {
      //选择交叉个体 
      i=sel();
      j=sel();

      //选择交叉位置 
      pos=randi(LEN-1);

     //交叉
     if(randd()<P_CORSS)
     {
       memcpy(next[k].x,cur[i].x,pos);
       memcpy(next[k].x+pos,cur[j].x+pos,LEN-pos);

       memcpy(next[k+1].x,cur[j].x,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)
     {
       pos=randi(LEN-1);
       next[k].x[pos]^=next[k].x[pos];

       pos=randi(LEN-1);
       next[k+1].x[pos]^=next[k+1].x[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();
 }

 //打印个体适应度和二进制编码 
 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)
   {
     tran();
   }
   ans=cur[0].fitness;
   for(int i=1;i<SIZE;i++) 
       ans=MAX(ans,cur[i].fitness);
   printf("%.6lf\n",ans);
 }

 int main()
 {
   srand((unsigned)time(NULL));

   init();
   GA();

   system("pause");
   return 0;
 }
    原文作者:遗传算法
    原文地址: https://blog.csdn.net/u012319493/article/details/50502979
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞