I have problem with order crossover in genetic algorithm. It should copy part of first parent between pointers to offspring, delete from second parent numbers(city number in my tsp problem) that exists in offspring, add one-by-one numbers, that left from second parent. For example:
parent1 . . . . . . . . . . . . . 3 4 1 5 2
parent2 . . . . . . . . . . . . . 4 2 1 5 3
firstPointer = 1, secondPointer = 3
offspring after first step: null 4 1 5 null
final offspring . . . . . . . . 2 4 1 5 3
Sorry for this point, they are just for alignment
Here the code, it should work for 2 offspring, algorithm the same like for first offspring
I think, problem could be in this line: parent2Copy[j] = null;
But not pretty sure, is it a copy or just reference
City.java
// just main part to understand structure not all `standard` methods
public class City {
private String name;
private int x, y;
public City(String name, int x, int y) {
this.name = name;
this.x = x;
this.y = y;
}
}
Main.java
public class Main {
public static void main(String[] args) {
City[] cities1 = {new City("3", 4, 6), new City("4", 4, 6), new City("1", 4, 6),
new City("5", 4, 6), new City("2", 4, 6)};
City[] cities2 = {new City("4", 4, 6), new City("2", 4, 6), new City("1", 4, 6),
new City("5", 4, 6), new City("3", 4, 6)};
Chromosome one = new Chromosome(cities1);
Chromosome two = new Chromosome(cities2);
System.out.println(one.toString());
System.out.println(two.toString());
Chromosome[] offspring = Crossover.orderedCrossover(one, two);
System.out.println(offspring[0].toString());
System.out.println(offspring[1].toString());
}
}
Crossover.java
public static Chromosome[] orderedCrossover(Chromosome parentOne, Chromosome parentTwo) {
Chromosome[] offspring = new Chromosome[2];
City[] parent1 = parentOne.getArray();
City[] parent2 = parentTwo.getArray();
City[] parent1Copy = new City[parent1.length];
City[] parent2Copy = new City[parent2.length];
City[] offspring1 = new City[parent1.length];
City[] offspring2 = new City[parent2.length];
int firstPointer = new Random().nextInt(parent1.length);
int secondPointer = new Random().nextInt(parent1.length - firstPointer) + firstPointer;
while (firstPointer >= secondPointer)
secondPointer = new Random().nextInt(parent1.length - firstPointer) + firstPointer;
for (int i = firstPointer; i < secondPointer; i++)
offspring1[i] = parent1[i];
for (int i = 0; i < parent1.length; i++) {
parent1Copy[i] = parent1[i];
parent2Copy[i] = parent2[i];
}
// remove cities from parent2Copy that exists in offspring1 and parent2Copy
for (int i = 0; i < offspring1.length; i++) {
for (int j = 0; j < parent2.length; j++) {
if (offspring1[i] == parent2[j])
parent2Copy[j] = null;
}
}
// adds last cities from parent2 to offspring1 empty slots
for (int i = 0; i < parent2.length; i++) {
for (int j = 0; j < parent2.length; j++) {
if (offspring1[i] == null)
if (parent2Copy[j] != null) {
offspring1[i] = parent2[j];
parent2Copy[j] = null;
break;
}
}
}
// put back cities to copy
for (int i = 0; i < parent1.length; i++)
parent2Copy[i] = parent2[i];
for (int i = firstPointer; i < secondPointer; i++)
offspring2[i] = parent2[i];
// remove cities from parent2 that exists in offspring and parent2
for (int i = 0; i < offspring2.length; i++) {
for (int j = 0; j < parent1.length; j++) {
if (offspring2[i] == parent1[j])
parent1Copy[j] = null;
}
}
// adds last cities from parent2 to offspring1 empty slots
for (int i = 0; i < parent1.length; i++) {
for (int j = 0; j < parent1.length; j++) {
if (offspring1[i] == null)
if (parent1Copy[j] != null) {
offspring2[i] = parent1[j];
parent1Copy[j] = null;
break;
}
}
}
offspring[0] = new Chromosome(offspring1);
offspring[1] = new Chromosome(offspring2);
return offspring;
}