0

以下のコードに問題があります。それは人口の進化の実装です。私の場合、最大限のフィットネスは毎回ローカルマキシマで打ち切られ、最大可能な値に達することができません。親切にも、必要な編集とその理由があることをお勧めします。遺伝的アルゴリズムの実装でローカル最大値に達した最大フィットネス

Individual.java

package genetic.algorithm.project; 

import java.util.Random; 

public class Individual { 

    public static int SIZE = 300; 
    private int[] genes = new int[SIZE]; 
    private double fitnessValue = 0.0; 


    // Getters and Setters 
    public void setGene(int index,int gene){ 
     this.genes[index] = gene; 
    } 

    public int getGene(int index){ 
     return this.genes[index]; 
    } 

    public void setFitnessValue(double fitness){ 
     this.fitnessValue = fitness; 
    } 

    public double getFitnessValue(){ 
     return this.fitnessValue; 
    } 

    //Function to generate a new individual with random set of genes 
    public void generateIndividual(){ 
     Random rand = new Random(); 
     for(int i=0;i<SIZE;i++){ 
      this.setGene(i, rand.nextInt(2)); 
     } 
    } 

    //Mutation Function 
    public void mutate(){ 
     Random rand = new Random(); 
     int index = rand.nextInt(SIZE); 
     this.setGene(index, 1-this.getGene(index)); // Flipping value of gene 
    } 

    //Function to set Fitness value of an individual 
    public int evaluate(){ 

     int fitness = 0; 
     for(int i=0; i<SIZE; ++i) { 
      fitness += this.getGene(i); 
     } 
     this.setFitnessValue(fitness); 
     return fitness; 
    } 

} 

Population.java

import java.util.Random; 

public class Population { 

    final static int ELITISM = 1; 
    final static int POP_SIZE = 200+ELITISM; //Population size + Elitism (1) 
    final static int MAX_ITER = 2000; 
    final static double MUTATION_RATE = 0.05; 
    final static double CROSSOVER_RATE = 0.7; 
    private static Random rand = new Random(); 

    private double totalFitness; 
    private Individual[] pop; 

    //Constructor 
    public Population(){ 
     pop = new Individual[POP_SIZE]; 
     //Initialising population 
     for(int i=0;i<POP_SIZE;i++){ 
      pop[i] = new Individual(); 
      pop[i].generateIndividual(); 

     } 
     this.evaluate(); 
    } 

    //Storing new generation in population 
    public void setPopulation(Individual[] newPop) { 
     this.pop = newPop; 
    } 


    //Method to find total fitness of population 
    public double evaluate(){ 
     this.totalFitness = 0.0; 
     for (int i = 0; i < POP_SIZE; i++) { 
      this.totalFitness += pop[i].evaluate(); 
     } 


     return this.totalFitness; 
    } 


    //Getters 
    public Individual getIndividual(int index) { 
     return pop[index]; 
    } 


    //Function to find fittest individual for elitism 
    public Individual getFittest() { 
     Individual fittest = pop[0]; 
     for (int i = 0; i < POP_SIZE; i++) { 
      if (fittest.getFitnessValue() <= getIndividual(i).getFitnessValue()) { 
       fittest = getIndividual(i); 
      } 
     } 
     return fittest; 
    } 

    //CROSSOVER Function : Takes 2 individuals and returns 2 new individuals 
    public static Individual[] crossover(Individual indiv1,Individual indiv2) { 
     Individual[] newIndiv = new Individual[2]; 
     newIndiv[0] = new Individual(); 
     newIndiv[1] = new Individual(); 
     int randPoint = rand.nextInt(Individual.SIZE); 
     int i; 
     for (i=0; i<randPoint; ++i) { 
      newIndiv[0].setGene(i, indiv1.getGene(i)); 
      newIndiv[1].setGene(i, indiv2.getGene(i)); 
     } 
     for (; i<Individual.SIZE; ++i) { 
      newIndiv[0].setGene(i, indiv2.getGene(i)); 
      newIndiv[1].setGene(i, indiv1.getGene(i)); 
     } 

     return newIndiv; 
    } 

    //Roulette Wheel Selection Function 
    public Individual rouletteWheelSelection() { 

     double randNum = rand.nextDouble() * this.totalFitness; 
     int idx; 

     for (idx=0; idx<POP_SIZE && randNum>0; idx++) { 
      randNum -= pop[idx].getFitnessValue(); 
     } 
     return pop[idx-1]; 
    } 

    //Main method 
    public static void main(String[] args) { 
     Population pop = new Population(); 
     Individual[] newPop = new Individual[POP_SIZE]; 
     Individual[] indiv = new Individual[2]; 
     //Current Population Stats 
     System.out.println("Total Fitness = "+pop.totalFitness); 
     System.out.println("Best Fitness = "+pop.getFittest().getFitnessValue()); 

     int count; 
     for(int iter=0;iter<MAX_ITER;iter++){ 
      count =0; 

       //Elitism 
       newPop[count] = pop.getFittest(); 
       count++; 

      //Creating new population 
      while(count < POP_SIZE){ 
       //Selecting parents 
       indiv[0] = pop.rouletteWheelSelection(); 
       indiv[1] = pop.rouletteWheelSelection(); 

       // Crossover 
       if (rand.nextDouble() < CROSSOVER_RATE) { 
        indiv = crossover(indiv[0], indiv[1]); 
       } 

       // Mutation 
       if (rand.nextDouble() < MUTATION_RATE) { 
        indiv[0].mutate(); 
       } 
       if (rand.nextDouble() < MUTATION_RATE) { 
        indiv[1].mutate(); 
       } 

       // add to new population 
       newPop[count] = indiv[0]; 
       newPop[count+1] = indiv[1]; 
       count += 2; 
      } 
      // Saving new population in pop 
      pop.setPopulation(newPop); 
      //Evaluating new population 
      pop.evaluate(); 
      System.out.print("Total Fitness = " + pop.totalFitness); 
      System.out.println(" ; Best Fitness = " +pop.getFittest().getFitnessValue()); 

     } 
     Individual bestIndiv = pop.getFittest(); 
    } 

} 

フィットネスの最大の可能な値は、私の場合は300ですが、それは常にstucks周り200-230。

public void setPopulation(Individual[] newPop) { 
    System.arraycopy(newPop, 0, this.pop, 0, POP_SIZE); 
} 

public void setPopulation(Individual[] newPop) { 
    this.pop = newPop; 
} 

、それが今で正常に動作します:

+0

これはGAの基本的な問題です。さまざまな種類のランダムな要因を導入するなど、彼らがチャンスを逃す可能性を減らす方法があります。これは、GAのより高度な側面、次にコードに固有の問題についての質問です。 – Carcigenicate

+0

私が試みようとしていた方法の1つは、適者生児を別の母集団に定期的に保存して、ローカルの最大値に固執したときにランダムに交配することでした。 – Carcigenicate

答えて

0

は、この機能を置き換え。

+0

最大限のフィットネスは、エリート主義を高めることによって、より迅速に達成することができます。 – Aman

関連する問題