1 package net.bmahe.genetics4j.core.combination.multipointcrossover;
2
3 import java.util.List;
4 import java.util.Objects;
5 import java.util.random.RandomGenerator;
6
7 import org.apache.commons.lang3.Validate;
8
9 import net.bmahe.genetics4j.core.chromosomes.Chromosome;
10 import net.bmahe.genetics4j.core.chromosomes.FloatChromosome;
11 import net.bmahe.genetics4j.core.combination.ChromosomeCombinator;
12 import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration;
13 import net.bmahe.genetics4j.core.spec.combination.MultiPointCrossover;
14
15 public class FloatChromosomeMultiPointCrossover<T extends Comparable<T>> implements ChromosomeCombinator<T> {
16
17 private final RandomGenerator randomGenerator;
18
19 private final MultiPointCrossover multiPointCrossoverPolicy;
20
21 public FloatChromosomeMultiPointCrossover(final RandomGenerator _randomGenerator,
22 final MultiPointCrossover _multiPointCrossoverPolicy) {
23 Objects.requireNonNull(_randomGenerator);
24 Objects.requireNonNull(_multiPointCrossoverPolicy);
25
26 this.randomGenerator = _randomGenerator;
27 this.multiPointCrossoverPolicy = _multiPointCrossoverPolicy;
28 }
29
30 @Override
31 public List<Chromosome> combine(final AbstractEAConfiguration<T> eaConfiguration, final Chromosome chromosome1,
32 final T firstParentFitness, final Chromosome chromosome2, final T secondParentFitness) {
33 Objects.requireNonNull(chromosome1);
34 Objects.requireNonNull(chromosome2);
35 Validate.isInstanceOf(FloatChromosome.class, chromosome1);
36 Validate.isInstanceOf(FloatChromosome.class, chromosome2);
37 Validate.isTrue(chromosome1.getNumAlleles() == chromosome2.getNumAlleles());
38
39 Validate.isTrue(multiPointCrossoverPolicy.numCrossovers() < chromosome1.getNumAlleles());
40 Validate.isTrue(multiPointCrossoverPolicy.numCrossovers() < chromosome2.getNumAlleles());
41
42 final int[] alleleSplits = randomGenerator.ints(0, chromosome1.getNumAlleles())
43 .distinct()
44 .limit(multiPointCrossoverPolicy.numCrossovers())
45 .sorted()
46 .toArray();
47
48 final FloatChromosome floatChromosome1 = (FloatChromosome) chromosome1;
49 final FloatChromosome floatChromosome2 = (FloatChromosome) chromosome2;
50
51 final int numAlleles = chromosome1.getNumAlleles();
52 final float[] firstChildValues = new float[numAlleles];
53 final float[] secondChildValues = new float[numAlleles];
54
55 boolean useChromosome1 = true;
56 int splitIndex = 0;
57 for (int i = 0; i < floatChromosome1.getNumAlleles(); i++) {
58
59 if (splitIndex < alleleSplits.length && i == alleleSplits[splitIndex]) {
60 splitIndex++;
61 useChromosome1 = !useChromosome1;
62 }
63
64 if (useChromosome1) {
65 firstChildValues[i] = floatChromosome1.getAllele(i);
66 secondChildValues[i] = floatChromosome2.getAllele(i);
67 } else {
68 firstChildValues[i] = floatChromosome2.getAllele(i);
69 secondChildValues[i] = floatChromosome1.getAllele(i);
70 }
71 }
72
73
74
75
76 final float minValue = floatChromosome1.getMinValue();
77 final float maxValue = floatChromosome2.getMaxValue();
78
79 return List.of(
80 new FloatChromosome(numAlleles, minValue, maxValue, firstChildValues),
81 new FloatChromosome(numAlleles, minValue, maxValue, secondChildValues));
82 }
83 }