crossoverParents method
Returns a List
of length 2 (2 children), each having a List of genes
created by crossing over parents' genes.
By default, the "chromosomes" are cut and crossed over at 2 random points,
like in human DNA. You can tweak this by specifying a different
crossoverPointsCount
.
The crossover only happens with crossoverProbability. Otherwise, exact copies of parents are returned.
Implementation
List<List<G>> crossoverParents(P a, P b, {int crossoverPointsCount = 2}) {
var random = math.Random();
if (random.nextDouble() < (1 - crossoverProbability)) {
// No crossover. Return genes as they are.
return [
List.from(a.genes, growable: false),
List.from(b.genes, growable: false)
];
}
assert(crossoverPointsCount < a.genes.length - 1);
var length = a.genes.length;
assert(length == b.genes.length);
var crossoverPoints = <int>{};
// Genes: 0 1 2 3 4 5 6
// Xpoints: 0 1 2 3 4 5
while (crossoverPoints.length < crossoverPointsCount) {
crossoverPoints.add(random.nextInt(length - 1));
}
var child1genes = List<G?>.filled(length, null);
var child2genes = List<G?>.filled(length, null);
var crossover = false;
for (var i = 0; i < length; i++) {
if (!crossover) {
child1genes[i] = a.genes[i];
child2genes[i] = b.genes[i];
} else {
child1genes[i] = b.genes[i];
child2genes[i] = a.genes[i];
}
if (crossoverPoints.contains(i)) {
crossover = !crossover;
}
}
return [
List<G>.from(child1genes, growable: false),
List<G>.from(child2genes, growable: false)
];
}