2016-11-17 50 views
-1

我正在創建一個用Java編寫的遺傳算法。變異函數以指定的概率翻轉數組中的位。 突變函數不保留數組(個體)的突變羣體。爲什麼我的深層數組副本在Java中爲循環更改外部值?

public static void mutation(Individual[] population, Individual[] mutatedOffspring, double mutationRate) { 

    // Iterate through gene, randomly select whether 
    // or not to change the value of the genome 
    // 
    System.out.println("\nMUTATION\n"); 
    Random mutant = new Random(); 
    Individual[] offspring = new Individual[POPULATION_SIZE]; 

    System.out.println("mutated offspring array"); 
    for (int i = 0; i < (population.length); i++) { 
     for (int j = 0; j < population[i].gene.length; j++) { 
      // flip bits in array at preset probability (0.1) 
      if (mutationRate > mutant.nextDouble()) { 
       if (population[i].gene[j] == 0) { 
        population[i].gene[j] = 1; 
       } else if (population[i].gene[j] == 1) { 
        population[i].gene[j] = 0; 
       } 
      } 
     } 
     // Deep copy contents of mutated array into new object array index (Individual) 
     fitness(population); 
     offspring[i] = new Individual(population[i].gene, population[i].fitness); 
     // Print both mutated array and copied array to show successful copy 
     System.out.println("offspring " + i + Arrays.toString(population[i].gene) + (population[i].fitness)); 
     System.out.println("copy:  " + i + Arrays.toString(offspring[i].gene) + (offspring[i].fitness)); 
    } 
    //print same array outside loop of population 
    System.out.println("\n"); 
    for (int i = 0; i < offspring.length; i++) { 
     System.out.println("copy:  " + i + Arrays.toString(offspring[i].gene) + (offspring[i].fitness)); 
    } 
    // deep copy outside p of population using .clone 
    for (int i = 0; i < offspring.length; i++) { 
     mutatedOffspring[i] = offspring[i].clone(); 
    } 

    fitness(mutatedOffspring); 
    System.out.println("\n"); 
    System.out.println("deep copied array using .clone() outside loop"); 

    for (int i = 0; i < mutatedOffspring.length; i++) { 
     System.out.println("offspring " + i + Arrays.toString(mutatedOffspring[i].gene) + (mutatedOffspring[i].fitness)); 
    } 
} 

聯大的第一次迭代之後,變異函數返回不是所有的不同的「突變」個人的個體,其在人羣中的最後個人的所有副本的人口。 (數組末尾的適應值尚未評估)。外循環

copy:  0[0, 0, 1, 0, 1, 1, 0, 1, 0, 1]4 
copy:  1[1, 0, 1, 0, 0, 0, 0, 0, 0, 1]3 
copy:  2[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]6 
copy:  3[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]8 
copy:  4[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]7 
copy:  5[0, 0, 1, 0, 1, 1, 0, 1, 0, 1]5 

深層副本使用.clone():

offspring 0[0, 0, 1, 0, 1, 1, 0, 0, 0, 1]4 
copy:  0[0, 0, 1, 0, 1, 1, 0, 0, 0, 1]4 
offspring 1[1, 0, 1, 0, 0, 0, 0, 0, 0, 1]3 
copy:  1[1, 0, 1, 0, 0, 0, 0, 0, 0, 1]3 
offspring 2[1, 1, 1, 1, 0, 0, 1, 1, 0, 0]6 
copy:  2[1, 1, 1, 1, 0, 0, 1, 1, 0, 0]6 
offspring 3[1, 1, 1, 1, 1, 0, 1, 1, 1, 0]8 
copy:  3[1, 1, 1, 1, 1, 0, 1, 1, 1, 0]8 
offspring 4[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]7 
copy:  4[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]7 
offspring 5[0, 0, 1, 0, 1, 1, 0, 1, 0, 1]5 
copy:  5[0, 0, 1, 0, 1, 1, 0, 1, 0, 1]5 

相同複製外人口的循環陣列:人口的環內

第一迭代

拷貝

offspring 0[0, 0, 1, 0, 1, 1, 0, 1, 0, 1]5 
offspring 1[1, 0, 1, 0, 0, 0, 0, 0, 0, 1]3 
offspring 2[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]7 
offspring 3[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]7 
offspring 4[0, 1, 1, 0, 0, 1, 1, 1, 1, 1]7 
offspring 5[0, 0, 1, 0, 1, 1, 0, 1, 0, 1]5 
外循環

copy:  0[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
copy:  1[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]5 
copy:  2[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]3 
copy:  3[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]5 
copy:  4[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
copy:  5[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 

深層副本使用.clone():

offspring 0[0, 1, 0, 0, 1, 1, 0, 0, 0, 1]4 
copy:  0[0, 1, 0, 0, 1, 1, 0, 0, 0, 1]4 
offspring 1[0, 1, 0, 0, 1, 1, 1, 1, 0, 0]5 
copy:  1[0, 1, 0, 0, 1, 1, 1, 1, 0, 0]5 
offspring 2[0, 0, 0, 0, 1, 1, 0, 1, 0, 0]3 
copy:  2[0, 0, 0, 0, 1, 1, 0, 1, 0, 0]3 
offspring 3[1, 1, 0, 1, 0, 0, 0, 1, 1, 0]5 
copy:  3[1, 1, 0, 1, 0, 0, 0, 1, 1, 0]5 
offspring 4[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
copy:  4[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
offspring 5[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
copy:  5[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 

相同複製外人口的循環陣列:人口的環內

第二迭代

拷貝

offspring 0[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
offspring 1[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
offspring 2[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
offspring 3[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
offspring 4[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 
offspring 5[0, 1, 0, 1, 0, 0, 0, 1, 1, 0]4 

我確定我正在創建一個新的個體,並在每次迭代後爲其分配我想要複製的個人的值。 我也試過在Individual類中創建一個clone()函數。

public Individual clone(){ 
    Individual individual = new Individual(gene, fitness); 
    individual.gene = gene; 
    individual.fitness = fitness; 
    return individual; 
} 

這兩種方法都產生相同的個體(或陣列),其是在循環內或出是否使用的最後一個個別的在突變人口副本的種羣。 在這個例子中,要複製的最後兩個數組是相同的,但我向你保證,所得到的後代/變異後代數組都是最後一個數組的副本。

我想保留GA的變異數組的人口工作。

+0

我應該注意到,當我運行這個方法100次自己在一個測試中它表現完美... –

回答

1

首先。我認爲你沒有正確解釋GA的基本原理。你是否在服用整個人羣,然後以10%的概率「變異」陣列中的每一個元素? 如果是這樣的話,你幾乎是人口中每一個元素的變異。這看起來不正確。您應該應用這個百分比來選擇每一代只有10%的人蔘與突變。

除此之外,我認爲你的問題是你沒有製作基因組的硬拷貝。

Individual individual = new Individual(gene, fitness); 
individual.gene = gene; 

當你做individual.gene =基因;你實際上是將這個新的個體指向「父母」的基因組。問題類似於this問題。

+0

謝謝,就是這樣,我的克隆沒有做每個基因組。 另外,是的,我認爲每個人羣中的每個人都是每一代突變的候選人?是的,我改變了突變的概率,每個基因組都可能發生了突變?我會再讀一遍,再次感謝。 –

相關問題