1 package net.bmahe.genetics4j.core.mutation.chromosome.creepmutation;
2
3 import java.util.Arrays;
4 import java.util.Objects;
5 import java.util.function.Supplier;
6 import java.util.random.RandomGenerator;
7
8 import org.apache.commons.lang3.Validate;
9
10 import net.bmahe.genetics4j.core.chromosomes.Chromosome;
11 import net.bmahe.genetics4j.core.chromosomes.IntChromosome;
12 import net.bmahe.genetics4j.core.mutation.chromosome.ChromosomeMutationHandler;
13 import net.bmahe.genetics4j.core.spec.chromosome.ChromosomeSpec;
14 import net.bmahe.genetics4j.core.spec.chromosome.IntChromosomeSpec;
15 import net.bmahe.genetics4j.core.spec.mutation.CreepMutation;
16 import net.bmahe.genetics4j.core.spec.mutation.MutationPolicy;
17 import net.bmahe.genetics4j.core.spec.statistics.distributions.Distribution;
18 import net.bmahe.genetics4j.core.util.DistributionUtils;
19
20 public class IntChromosomeCreepMutationHandler implements ChromosomeMutationHandler<IntChromosome> {
21
22 private final RandomGenerator randomGenerator;
23
24 public IntChromosomeCreepMutationHandler(final RandomGenerator _randomGenerator) {
25 Objects.requireNonNull(_randomGenerator);
26
27 this.randomGenerator = _randomGenerator;
28 }
29
30 @Override
31 public boolean canHandle(final MutationPolicy mutationPolicy, final ChromosomeSpec chromosome) {
32 Objects.requireNonNull(mutationPolicy);
33 Objects.requireNonNull(chromosome);
34
35 return mutationPolicy instanceof CreepMutation && chromosome instanceof IntChromosomeSpec;
36 }
37
38 @Override
39 public IntChromosome mutate(final MutationPolicy mutationPolicy, final Chromosome chromosome) {
40 Objects.requireNonNull(mutationPolicy);
41 Objects.requireNonNull(chromosome);
42 Validate.isInstanceOf(CreepMutation.class, mutationPolicy);
43 Validate.isInstanceOf(IntChromosome.class, chromosome);
44
45 final var intChromosome = (IntChromosome) chromosome;
46 final var creepMutation = (CreepMutation) mutationPolicy;
47
48 final var minValue = intChromosome.getMinValue();
49 final var maxValue = intChromosome.getMaxValue();
50 final Distribution distribution = creepMutation.distribution();
51
52 final Supplier<Double> distributionValueSupplier = DistributionUtils
53 .distributionValueSupplier(randomGenerator, minValue, maxValue, distribution);
54
55 final int[] newValues = Arrays.copyOf(intChromosome.getValues(), intChromosome.getNumAlleles());
56
57 final int alleleFlipIndex = randomGenerator.nextInt(intChromosome.getNumAlleles());
58 newValues[alleleFlipIndex] += distributionValueSupplier.get();
59
60 if (newValues[alleleFlipIndex] > maxValue) {
61 newValues[alleleFlipIndex] = maxValue;
62 } else if (newValues[alleleFlipIndex] < minValue) {
63 newValues[alleleFlipIndex] = minValue;
64 }
65
66 return new IntChromosome(intChromosome.getSize(),
67 intChromosome.getMinValue(),
68 intChromosome.getMaxValue(),
69 newValues);
70 }
71 }