-1

I'm creating a Genetic Algorithm written in Java. The mutation function flips the bits in the array at an assigned probability. The mutation function is not retaining the mutated population of arrays (Individuals).

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

After the first iteration of the GA, the mutation function returns a population of Individuals, which are all copies of the last individual in the population, not of all the different 'mutated' individuals. (The fitness values at the end of the arrays haven't been evaluated).

1st ITERATION

copy within loop of population:

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

same copied array outside loop of population:

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

deep copy using .clone() outside loop

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

2nd ITERATION

copy within loop of population:

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

same copied arrays outside loop of population:

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

deep copy using .clone() outside loop

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

I'm sure I'm doing a deep copy by creating a new individual and assigning it the values of the Individual I wish to copy to it after each iteration. I've also tried creating a clone() function in the Individual class.

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

Both methods produce population of identical Individuals (or arrays) which are a copy of the last Individual in the mutated population whether used inside the loop or out. In the example the last two arrays to copy are the same but I assure you the resulting offspring/ mutated offspring arrays are all a copy of the last one.

I want to retain a population of the mutated arrays for the GA to work.

1 Answers1

1

First of all. I think you are not correctly interpreting the GA fundamentals. Are you taking the whole population, and then "mutating" every single element of the array with 10% probability? If that is the case, you are mutation almost every single element of the population. That doesn't seem correct. You should apply this percentage to select ONLY a 10% of the population to participate in mutation every generation.

Besides that, I think your problem is that you are not making a hard-copy of the genome.

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

When you do individual.gene = gene; you are actually pointing this new individual to the genome of the "parent". Is a problem similar to this question.

Community
  • 1
  • 1
Enrique Arriaga
  • 499
  • 2
  • 6
  • Thanks, that was it, my clone wasn't doing each genome. Also, yes I thought each individual in a population is a candidate for mutation in each generation? And yes I change the probability of mutation and each genome is potentially mutated? I'll read up on this, thanks again. – Billy Martin Nov 18 '16 at 11:19