【问题标题】:Fitness for a genetic algorithm refuses to budge遗传算法的适应性拒绝让步
【发布时间】:2014-12-30 05:11:17
【问题描述】:

我正在制作一个遗传算法来将字符演变成“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

【问题讨论】:

  • 您可能需要在代码中放置日志或 System.out 以查看代码卡住的确切位置。还打印所有涉及的变量,以便您可以仔细检查对象当时所处的状态。通过切换断点进行调试,可以在 Eclipse IDE 中轻松完成此过程。这只有在您的应用程序可以在 Eclipse 中执行时才有效。
  • 好的,课末贴出来。
  • 你能发布你的健身功能的源代码吗?

标签: java algorithm genetic-algorithm


【解决方案1】:

让我们仔细看看你的静态getFitness(Chromosome chrom)函数的sn-p:

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 表示),因此最适合的将是差异较小的那个,因为它更接近实际字符。根据经验,大多数优化问题都是关于找到最小值,因此您应该始终仔细检查。

尝试解决这两个问题,如果您在进化过程中仍然遇到问题,请告诉我们。

【讨论】:

  • 快到了!!!这解决了很多错误,所以我必须对此表示衷心的感谢。但是,我的健康指数在大约 100 代左右后会冻结到某个点。我将编辑我的原始帖子以向您展示我的意思。
  • 您还可以通过注释掉旧行并放入当前行来编辑代码吗?这样我们就可以查看当前的进度状态
  • 我应该在人口类别中添加精英主义以帮助避免陷入局部最大值吗?
  • 糟糕,我复制了错误的人口 getFittest() 语句。
  • 成功!非常感谢您的回答!奇迹般有效!我有一种感觉,但从不费心仔细检查,因为经验丰富的同行编辑总是最好的。 :D
猜你喜欢
  • 2020-05-12
  • 1970-01-01
  • 2012-07-07
  • 2023-03-16
  • 2017-12-16
  • 2023-02-20
  • 2011-12-21
  • 2020-10-14
  • 2011-10-07
相关资源
最近更新 更多