为什么我的深度数组副本会在Java中改变它的循环值?

时间:2016-11-17 16:05:20

标签: java arrays genetic-algorithm deep-copy mutation

我正在创建一个用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));
    }
}

在GA的第一次迭代之后,突变函数返回个体群体,这些群体是群体中最后个体的所有副本,而不是所有不同的#变异&# 39;个人。 (阵列末尾的适应值尚未经过评估)。

第一次迭代

在人口循环中复制:

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

相同复制的数组外部循环:

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, 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

第二次迭代

在人口循环中复制:

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

相同的复制数组在人口循环之外:

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, 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工作。

1 个答案:

答案 0 :(得分:1)

首先。我认为你没有正确解释GA的基本原理。您是否占用了整个人口,然后以10%的概率“变异”阵列中的每个元素? 如果是这种情况,那么几乎每个人口都会突变。这似乎不正确。您应该应用这个百分比来选择每年只有10%的人口参与突变。

除此之外,我认为你的问题是你没有制作基因组的硬拷贝。

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

当你做个人时.gene = gene;你实际上是把这个新个体指向“父母”的基因组。问题类似于this问题。