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.