遗传算法----定向进化---字符

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

遗传算法借鉴了达尔文的进化论思想,不断地接近需求形态。
遗传算法遵循这个个规则。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代\n",generation);
	if(flag==0)
	  {
	    printf("繁衍第%d后生成目标对象\n",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("\n");
    }
}
----选择父本
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\n",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!!\n");
    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\n",fatherGroup[t]);
	  t++;
	}
    }
  printf("剩余亲代为:%d\n",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;
      }
效果图:
}
posted @ 2020-01-14 19:35  秋风不识春  阅读(245)  评论(0编辑  收藏  举报