2016-12-27 3 views
2

У меня возникли проблемы с созданием генетического алгоритма в java. Я конкурирую в онлайн-конкурсе GA. Я пытаюсь сохранить лучший результат каждый раз обратно в индекс 0, но он просто становится ссылкой на исходный индекс. Значение, когда я развиваю остальные индексы, если он развивает исходный индекс лучших членов, я его теряю.Генетический алгоритм в Java-проблемах

Я пробовал обрезать его методом getClone, который преобразует данные объектов в массив int и создает из него новый объект.

Индивидуальный класс: класс

class Individual { 
    public int[] angle; 
    public int[] thrust; 
    public double fitness; 
    public Individual(){ 
     angle = new int[2]; 
     thrust = new int[2]; 
     for (int i = 0; i < 2; i++) {  
      this.angle[i] = ThreadLocalRandom.current().nextInt(0, 37) - 18; 
      this.thrust[i] = ThreadLocalRandom.current().nextInt(0, 202); 
      this.thrust[i] = ((this.thrust[i] == 201) ? 650 : this.thrust[i]); 
     } 
     this.fitness = Double.MIN_VALUE; 
    } 

    public Individual(int[][] genes, double f){ 
     this.fitness = f; 
     angle = new int[2]; 
     thrust = new int[2]; 
     this.angle[0] = genes[0][0]; 
     this.angle[1] = genes[0][1]; 
     this.thrust[0] = genes[1][0]; 
     this.thrust[1] = genes[1][1];  
    } 

    public Individual getClone() { 
     int[][] genes = new int[2][2]; 
     genes[0][0] = (int)this.angle[0]; 
     genes[0][1] = (int)this.angle[1]; 
     genes[1][0] = (int)this.thrust[0]; 
     genes[1][1] = (int)this.thrust[1]; 
     return (new Individual(genes, this.fitness)); 
    } 

    public Individual crossover(Individual other) { 
     int[][] genes = new int[2][2]; 
     genes[0][0] = (int)((this.angle[0] + other.angle[0])/2); 
     genes[0][1] = (int)((this.angle[1] + other.angle[1])/2); 
     genes[1][0] = ((this.thrust[0] == 650 || other.thrust[0] == 650) ? 650: (int)((this.thrust[0] + other.thrust[0])/2)); 
     genes[1][1] = ((this.thrust[1] == 650 || other.thrust[1] == 650) ? 650: (int)((this.thrust[1] + other.thrust[1])/2)); 
     return (new Individual(genes, Double.MIN_VALUE)); 
    } 

    public void mutate() { 
     for (int i = 0; i < 2; i++) { 
      if(ThreadLocalRandom.current().nextInt(0, 2)==1) { 
       this.angle[i] = ThreadLocalRandom.current().nextInt(0, 37) - 18; 
      } 
      if(ThreadLocalRandom.current().nextInt(0, 2)==1) { 
       this.thrust[i] = ThreadLocalRandom.current().nextInt(0, 202); 
       this.thrust[i] = ((this.thrust[i] == 201) ? 650 : this.thrust[i]); 
      } 
     } 
    } 

Население:

class Population { 
    public Individual[] individuals; 

    public Population(int populationSize) { 
     individuals = new Individual[populationSize]; 
     for (int i = 0; i < populationSize; i ++) { 
      individuals[i] = new Individual(); 
     } 
    } 

    public void resetFitness() { 
     for (int i = 0; i < individuals.length; i++) { 
      individuals[i].fitness = Double.MIN_VALUE; 
     } 
    } 
    public void setIndividual(int i, Individual indiv) { 
     individuals[i] = indiv.getClone(); 
    } 

    public Individual getIndividual(int i) { 
     return individuals[i].getClone(); 
    } 

    public int size() { 
     return this.individuals.length;  
    } 
    public Individual getFittest() { 
     int fittest = 0; 
     // Loop through individuals to find fittest 
     for (int i = 0; i < individuals.length; i++) { 
      if (individuals[i].fitness > individuals[fittest].fitness) { 
       fittest = i; 
      } 
     } 
     return individuals[fittest].getClone(); 
    } 
} 

первой необходимости из сим-класса:

class simGA { 
    private Population pop; 
    private final static int TSIZE = 5; //tournement size 

    public simGA (int poolsize) { 
     this.pop = new Population(poolsize); 
    } 

    public Individual search(int generations, int totalMoves) { 
     //this.pop.resetFitness(); 
     for (int g = 0; g < generations; g++) { 
      for (int i = 0; i < this.pop.individuals.length; i++) { 
       this.pop.individuals[i].fitness = sim(this.pop.individuals[i],totalMoves); 
      } 
      System.err.print("Generation " + g + " "); 
      this.pop = evolvePopulation(this.pop); 
     } 
     return pop.getFittest(); 
    } 

    private Population evolvePopulation(Population p) { 
     //save fittest 
     Population tempPop = new Population(p.individuals.length); 
     tempPop.setIndividual(0, p.getFittest().getClone()); 
     System.err.print("Best move: " + tempPop.individuals[0].fitness); 
     System.err.println(); 
     for (int i = 1; i < p.individuals.length; i++) { 
      Individual indiv1 = tournamentSelection(p); 
      Individual indiv2 = tournamentSelection(p); 
      Individual newIndiv = indiv1.crossover(indiv2); 
      newIndiv.mutate(); 
      tempPop.setIndividual(i, newIndiv.getClone()); 
     } 
     return tempPop; 
    } 

    // Select individuals for crossover 
    private Individual tournamentSelection(Population pop) { 
     // Create a tournament population 
     Population tournament = new Population(TSIZE); 
     // For each place in the tournament get a random individual 
     for (int i = 0; i < TSIZE; i++) { 
      int randomId = ThreadLocalRandom.current().nextInt(1, this.pop.individuals.length); 
      tournament.setIndividual(i, pop.getIndividual(randomId).getClone()); 
     } 
     // Get the fittest 
     return tournament.getFittest().getClone(); 
    } 

    private double sim(Individual s, int moves) { 
     return score; //score of simmed moves 
    } 

Как я могу убедиться, что лучший индивидуальный становится сохранен , а не как ссылка? Когда я печатаю ошибку, лучший результат, иногда она теряется и выбирается худший результат. Я не думаю, что это обязательно проблема клонирования объекта, я могу клонировать игровые объекты, которые имитируются просто отлично, перезагружая их каждый прогон.

Как я уже сказал, это конкурс, поэтому я не могу использовать какие-либо библиотеки на сайте, а также причина, по которой я не размещаю полный код, тонкости симулятора, который сам оценивает ходы, быть просто отданным. Но хватит, чтобы сказать, что баллы возвращаются, как и ожидалось, при движении на бумаге.

Ответ от IWS, я думал, что мой метод getClone выполняет глубокую копию.

Reference используется рядом виками и других знаний о генетических алгоритмах: http://www.theprojectspot.com/tutorial-post/creating-a-genetic-algorithm-for-beginners/3

Я установил его не resimming индивида с индексом 0. Однако это означает, что есть другая проблема с моим кодом, не связанным с вопросом.

+0

Разве это не глубокая копия или проблема с мелкой копией? – NWS

+0

, чтобы сохранить его, вы должны создать новый объект и сохранить во всех значениях атрибута. В некоторых случаях я предпочитаю хранить коллекцию этого нового объекта. – bilelovitch

ответ

1
Individual newIndiv = indiv1.crossover(indiv2); 

Вышеуказанная линия сбрасывает фитнес на Double.MIN_VALUE. Итак, всякий раз, когда вызывается evolvePopulation, наиболее приспособлен только индивидуум по индексу 0.

+0

Это правильно, но я продолжаю проигрывать индивидууму по индексу 0, когда хочу его сохранить. –

+0

Эта строка сбрасывает все индексы: this.pop.individuals [i] .fitness = sim (this.pop.individuals [i], totalMoves); ' – Azodious

1

Я исправил его, не обновляя индивидууму с индексом 0. Однако это означает, что есть другой вопрос, связанный с тем, что мой код не имеет отношения к вопросу, так как повторное обследование одного и того же человека с той же точки времени, что и раньше, не должно меняться фитнес.

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

  • Нет связанных вопросов^_^