2014-12-29 1 views
0

Я создаю генетический алгоритм для разработки символов в «Hello World», но когда я выполняю программу, он пересекает один раз и остается неизменным для остальной части прогона. Я точно знаю, что мой метод crossOver и mutate работает, но что-то не так в моем методе selectParents?Фитнес для генетического алгоритма отказывается сдвигаться

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

Вам, вероятно, понадобится разместить в коде журналы или System.out, чтобы узнать, где именно застрял код. Также распечатайте все задействованные переменные, чтобы вы могли проверить состояние, в котором объект находится в этой точке. Этот процесс можно легко выполнить в Eclipse IDE, переключив точку прерывания для отладки. Это работает только в том случае, если ваше приложение может превзойти в Eclipse. –

+0

Хорошо, отправил его в конце класса. – monsterbasher

+0

Не могли бы вы опубликовать исходный код для вашей функции фитнеса? – NPE

ответ

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. Вы не зацикливаете на все гены, поэтому вам, вероятно, следует избавиться от первого возвращения.

Другая вещь, которую я смутил, - это ваша функция . Здесь вы говорите, что самая сильная хромосома имеет самое высокое значение для фитнеса:

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

Но это действительно так? Помните, вы вычитаете генотипы персонажей (их представление Int), поэтому самым приспособленным будет тот, у которого меньшая разница, потому что он ближе к фактическому персонажу. Как правило, можно сказать, что большинство проблем оптимизации - это поиск минимума, поэтому вы должны всегда дважды проверять это.

Постарайтесь исправить эти вещи и сообщите нам, если вы все еще испытываете проблемы с эволюционным процессом.

+0

Практически там !!! Это фиксировало много ошибок, поэтому я должен поблагодарить вас за это. Тем не менее, мой фитнес-номер замерзает до определенного момента после примерно 100 или около того поколений. Я отредактирую свое оригинальное сообщение, чтобы показать вам, что я имею в виду. – monsterbasher

+0

Не могли бы вы также отредактировать код, комментируя старые строки и вставляя текущие? Таким образом, мы можем взглянуть на текущее состояние прогресса. – zunder

+0

Должен ли я добавить элитизм в класс популяции, чтобы не зависеть от локального максимума? – monsterbasher

Смежные вопросы