zoukankan      html  css  js  c++  java
  • 遗传算法----定向进化---字符

    遗传算法---字符串向确定的方向进化

    遗传算法借鉴了达尔文的进化论思想,不断地接近需求形态。
    遗传算法遵循这个个规则。1、有一个初始化种群。2、有一个筛选种群中成员的规则---不合适者淘汰、相似者保存。3、确定交配权利---优先度。4、选择亲本产生子代----如何选择亲本?如何产生子代?产生子代的过程中是否要突变?
    如果要生成一个指定的字符串,选择合适的亲本至关重要。如果亲本选择不那么恰当,生成目标字符串的可能性会很低。可能繁衍几百万代还没有一个目标字符串。选择的好,可能产生七八代就有目标字符串。---即淘汰规则很重要。
    函数逻辑图:
    相应代码
    全局变量和结构体:
    #include<stdio.h>
    #include<time.h>
    #include<stdlib.h>
    
    #define D 5
    #define G 100
    const double mutation=0.01;//随机生成1-100的数,再转化为小数。
    typedef struct DNA{
      char dna[D];
    }DNA;
    
    void judge();
    void chose();
    void reprodution();
    /*初始化种群---*/
    /*选择----创建适应度--交配池*/
    /*繁殖----根据适应度选择亲代---交叉--突变--新种群替代旧种群*/
    /*回到选择*/
    DNA group[G];
    double priority[G];
    int flag=1;

    主函数:
    int main(){
          init();
          int generation=-1;
          while(flag){
    	chose();
    	generation++;
    	printf("已经繁衍%d代
    ",generation);
    	if(flag==0)
    	  {
    	    printf("繁衍第%d后生成目标对象
    ",generation);
    	    getchar();
    	  }
         }
       }
    
    init函数---初始化种群:

    void  init(){/*初始化种群DNA */
      int i=0,t;
      srand(time(NULL));
      for(i=0;i<G;i++)
        {
          for(t=0;t<D;t++){
    	  group[i].dna[t]=rand()%((25)+1)+65;
    	  //printf("%c",group[i].dna[t]);
          }
          //printf("
    ");
        }
    }
    ----选择父本
    void chose(){/*生成种群中个体的适应度----作为繁殖时被选作父本的概率*/
        char standard[D]={'G','O','O','N','K'};//进化方向字符
        /*优先度设置为0、1、2、3、4*/
        int i,j;
        double p=0;
        for(i=0;i<G;i++)
          {
    	p=0;
    	for(j=0;j<D;j++)
    	  {
    	    if(group[i].dna[j]==standard[j])
    	      p++;
    	  }
    	priority[i]=p/D;
    	/*if(priority[i]!=0)
    	printf("适应度为=%lf
    ",priority[i]);*/
    }
        judge();
    }
    
    ---判断有没有符合要求的个体
    void  judge(){
        int i;
        for(i=0;i<G;i++)
          if(priority[i]==1.0)
    	{
    	  flag=0;
    	  break;
    	}
        if(flag==0)
            printf("sucess!!
    ");
        if(flag!=0)
        	reprodution();
    }
    
    -----生成子代
    void reprodution(){
        /*根据优先度确定对象被选到的概率*/
        /*优先率为0,则淘汰不具有产生子代的权利。*/
      int i=0,j,j2;//
      int t=0;//fatherGroup有数据的总个体
      int q=0;
      int f1=0;//分割点
      /*创建fatherGroup*/
      DNA fatherGroup[G]={0};
      for(i=0;i<G;i++)
        {
          if(priority[i]!=0)
    	{
    	  for(j=0;j<D;j++){
    	  fatherGroup[t].dna[j]=group[i].dna[j];
    	  }
    	  printf("%s
    ",fatherGroup[t]);
    	  t++;
    	}
        }
      printf("剩余亲代为:%d
    ",t);
      /*从fatherGroup中选择两个亲代*/
      srand(time(NULL));
      for(i=0;i<G;i++){/*生成新种群取代旧种群---种群个体总数不变*/
    
          j=rand()%(t+1);
          j2=rand()%(t+1);
          /*交叉---取亲代j和j2的某个字母*/
          f1=rand()%D;
          for(q=0;q<=f1;q++){
    	  group[i].dna[q]=fatherGroup[j].dna[q];
          }
          for(q=f1+1;q<D;q++){
    	  group[i].dna[q]=fatherGroup[j2].dna[q];
          }
      }
      /*突变----新种群个体基因突变----个体逐个基因进行能否突变的检测*/
      //srand(time(NULL));
      for(i=0;i<G;i++)
        for(q=0;q<D;q++)
          {
    
    	if((rand()%100+1)==(mutation*100))/*突变判断*/
    	  group[i].dna[q]=rand()%((25)+1)+65;
          }
    效果图:
    
    }
  • 相关阅读:
    表模块模式与事务脚本模式的代码编写
    解决方案下显示的网站名称被追加编号的问题解决方法
    应用层代码
    关于CodeReview(java)(转)
    关于事务的几个概念介绍(转)
    关于JVM的ClassLoader(转)
    svn相关
    .subversion
    linux用户与组的管理(命令加入、手动加入、加入组、用户之间的切换)
    回调函数
  • 原文地址:https://www.cnblogs.com/deciduousmap/p/12193729.html
Copyright © 2011-2022 走看看