1 package net.bmahe.genetics4j.core.mutation.chromosome.swapmutation;
2
3 import java.util.Arrays;
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.DoubleChromosome;
11 import net.bmahe.genetics4j.core.mutation.chromosome.ChromosomeMutationHandler;
12 import net.bmahe.genetics4j.core.spec.chromosome.ChromosomeSpec;
13 import net.bmahe.genetics4j.core.spec.chromosome.DoubleChromosomeSpec;
14 import net.bmahe.genetics4j.core.spec.mutation.MutationPolicy;
15 import net.bmahe.genetics4j.core.spec.mutation.SwapMutation;
16
17 public class DoubleChromosomeSwapMutationHandler implements ChromosomeMutationHandler<DoubleChromosome> {
18
19 private final RandomGenerator randomGenerator;
20
21 public DoubleChromosomeSwapMutationHandler(final RandomGenerator _randomGenerator) {
22 Objects.requireNonNull(_randomGenerator);
23
24 this.randomGenerator = _randomGenerator;
25 }
26
27 @Override
28 public boolean canHandle(final MutationPolicy mutationPolicy, final ChromosomeSpec chromosome) {
29 Objects.requireNonNull(mutationPolicy);
30 Objects.requireNonNull(chromosome);
31
32 return mutationPolicy instanceof SwapMutation && chromosome instanceof DoubleChromosomeSpec;
33 }
34
35 @Override
36 public DoubleChromosome mutate(final MutationPolicy mutationPolicy, final Chromosome chromosome) {
37 Objects.requireNonNull(mutationPolicy);
38 Objects.requireNonNull(chromosome);
39 Validate.isInstanceOf(SwapMutation.class, mutationPolicy);
40 Validate.isInstanceOf(DoubleChromosome.class, chromosome);
41
42 final SwapMutation swapMutation = (SwapMutation) mutationPolicy;
43 final int numSwap = swapMutation.isNumSwapFixed() ? swapMutation.numSwap()
44 : 1 + randomGenerator.nextInt(swapMutation.numSwap());
45
46 final DoubleChromosome doubleChromosome = (DoubleChromosome) chromosome;
47
48 final double[] values = doubleChromosome.getValues();
49 final double[] newValues = Arrays.copyOf(values, values.length);
50
51 for (int i = 0; i < numSwap; i++) {
52 final int value1Index = randomGenerator.nextInt(doubleChromosome.getNumAlleles());
53 final int value2Index = randomGenerator.nextInt(doubleChromosome.getNumAlleles());
54
55 final double value1 = newValues[value1Index];
56 final double value2 = newValues[value2Index];
57
58 newValues[value1Index] = value2;
59 newValues[value2Index] = value1;
60 }
61
62 return new DoubleChromosome(doubleChromosome.getSize(),
63 doubleChromosome.getMinValue(),
64 doubleChromosome.getMaxValue(),
65 newValues);
66 }
67 }