遗传算法的适应性拒绝让步

时间:2014-12-29 18:01:47

标签: java algorithm genetic-algorithm

我正在制作遗传算法以将字符演变为“Hello World”,但是当我执行该程序时,它会跨越一次并在剩余的运行中保持相同。我知道我的crossOver和mutate方法有效,但是我的chooseParents方法有问题吗?

    public class Algorithm{
       private static int newPopLength = 5;
       private static final double MUTATE_RATE = .015;
       private static final double CROSSOVER_RATE = .6;

       public static Population evolvePopulation(Population pop){
          Population newPopulation = new Population(pop.size());
       //crossover
          for(int  x = 0; x<pop.size(); x++){
          //chooses two parents for crossover
             Chromosome chrom1 = chooseParents(pop);
             Chromosome chrom2 = chooseParents(pop);
             Chromosome newChild = crossOver(chrom1, chrom2);
             newPopulation.setChromosome(x, newChild);
          }
       //mutate
          for(int x = 0; x < pop.size(); x++){
             mutate(newPopulation.getChromosome(x));
          }
          return newPopulation;
       } 

       //crossover method
       public static Chromosome crossOver(Chromosome chrom1, Chromosome chrom2){
          Chromosome childChrom = new Chromosome();
          childChrom.generateChromosome();
       //Creates and generates childChromosome

          char []arr1 = chrom1.getChromosome();
          char []arr2 = chrom2.getChromosome();
          char []childArr = new char[arr1.length];

       //crosses over by 1/2 of each array
          for(int x = 0; x<arr2.length; x++){
             if(x <= Math.round(arr1.length / 2)){
                childArr[x] = arr1[x];
             }
             else{
                childArr[x] = arr2[x];
             }
          }
          for(int x = 0; x<childArr.length; x++){
             childChrom.setGene(childArr[x], x);
          }
          return childChrom;
       }
       //mutates chromosome by selecting a random point and replacing it with a random char
       public static void mutate(Chromosome chrom){
          if(Math.random() <= MUTATE_RATE){
             int rand = Math.round((int)(Math.random() * chrom.size()));
             chrom.setGene((char)((Math.random()*25) + 97), rand);
          }
       }
       private static Chromosome chooseParents(Population pop){
          Population newPopulation = new Population(newPopLength);

          Chromosome fittest = new Chromosome();
          for(int x = 0; x<newPopulation.size(); x++){
          //randomlu chooses 5 chromosomes
             Chromosome newChrom = pop.getChromosome((int)(Math.random()*pop.size()));
             newPopulation.setChromosome(x, newChrom);

          }
          return newPopulation.getFittest();

       }
    }
public class FitnessCalc{
   private static char solution[] = new char[Chromosome.getDefaultLength()];
   public static void setSolution(String word){
      solution = word.toCharArray();
   }

   public static char[] getSolution(){
      return solution;
   }
   public static int getFitness(Chromosome chrom){
      int fitness = 0;
      String chromWord = String.valueOf(chrom);
      char []chromArray = chromWord.toCharArray(); 

      for(int x = 0; x< solution.length;x++){
         //return 
fitness += Math.abs((int)(chrom.getGene(x)) - (int)(solution[x]));
      }
      return fitness;
   }


   public static int maxFitness(){
      int maxFitness =10241024;
      return maxFitness;
   }
}


   public Chromosome getFittest(){
      Chromosome fittest = new Chromosome();
      fittest.generateChromosome();
      for(int x = 0; x<size(); x++){
   if(FitnessCalc.getFitness(getChromosome(x))<= FitnessCalc.getFitness(fittest)){
         //if(FitnessCalc.getFitness(getChromosome(x)) >= FitnessCalc.getFitness(fittest)){
            fittest =  getChromosome(x);
         }
      }

      return fittest;
   }

输出:

Generation  992 Fittest Hello2aorld Fitness 28
Generation  993 Fittest Hello2aorld Fitness 28
Generation  994 Fittest Hello2aorld Fitness 28
Generation  995 Fittest Hello2aorld Fitness 28
Generation  996 Fittest Hello2aorld Fitness 28
Generation  997 Fittest Hello2aorld Fitness 28
Generation  998 Fittest Hello2aorld Fitness 28
Generation  999 Fittest Hello2aorld Fitness 28
Generation 1000 Fittest Hello2aorld Fitness 28


Generation 998 Fittest 2ello'aorld Fitness 39
Generation 999 Fittest 2ello'aorld Fitness 39
Generation 1000 Fittest 2ello'aorld Fitness 39

Generation 998 Fittest Sello,Porld Fitness 30
Generation 999 Fittest Sello,Porld Fitness 30
Generation 1000 Fittest Sello,Porld Fitness 30

1 个答案:

答案 0 :(得分:3)

让我们仔细看看静态getFitness(Chromosome chrom)函数的片段:

for(int x = 0; x< solution.length;x++){
  return fitness += Math.abs((int)(chrom.getGene(x)) - (int)(solution[x]));
}
return fitness;

你想在这里积累健身吗?如果是这样,它就不起作用了,因为你在x = 0时添加了绝对差值后立即返回适应度。你没有在那里循环所有的基因,所以你应该摆脱第一次回归。

我感到困惑的另一件事是你的getFittest()功能。在这里,您说最适合的染色体具有最高的适应值:

if(FitnessCalc.getFitness(getChromosome(x)) >= FitnessCalc.getFitness(fittest)){
  fittest =  getChromosome(x);
}

但这是真的吗?请记住,您正在减去字符基因型(它们的Int表示),因此最适合的是具有较小差异的那个,因为它更接近实际字符。根据经验,可以说大多数优化问题都是关于找到最小值,所以你应该总是仔细检查它。

尝试修复这两件事,如果您仍然遇到进化过程中的问题,请告诉我们。