2016-12-27 120 views
2

我無法使用Java創建一個遺傳算法。我參加了在線GA比賽。我試圖保存每次返回到索引0的最佳結果,但它只是成爲對原始索引的引用。這意味着當我發展其餘的索引時,如果它演變出最好的成員原始索引,我就會失去它。遺傳算法的Java問題

我試圖與該對象數據轉換到和int數組,並從它創建一個新對象getClone方法勻場它。

個人類:

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(); 
    } 
} 

從SIM類的必需品:

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 
    } 

我怎樣才能確保最佳的個體得到保存,不作爲參考?當我錯誤地打印出最佳分數時,有時會丟失並選擇更差的得分動作。我不認爲它必然是一個克隆對象的問題,我可以克隆模擬得很好的遊戲對象,每次運行都重置它們。

正如我所說,這是一個比賽,所以我不能在網站上使用任何庫,也是我沒有發佈完整代碼的原因,模擬器的錯綜複雜的自我評分的動作不是隻是放棄了。但足以說明,如果在紙上制定計劃,分數會按預期恢復。

我到新創建的反應,我想我的getClone方法是做一個深拷貝。維基和其他知識的旁邊用遺傳算法

參考:http://www.theprojectspot.com/tutorial-post/creating-a-genetic-algorithm-for-beginners/3

我已經不resimming索引爲0的個體固定它然而,這意味着還有其他的問題,我的代碼不相關的問題。

+0

這不是一個深拷貝vs淺拷貝問題嗎? – NWS

+0

保存它,你必須創建一個新的對象,並存儲到所有的屬性值。在某些cas中,我更願意存儲這個新對象的集合。 – 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不是resimming個人固定它然而,這意味着還有其他的問題,我的代碼不相關的問題,因爲如之前的時間從同一點resimming同一個人不應該改變它的健身。