01 package org.jenetics.ext;
02
03 import java.util.stream.IntStream;
04
05 import org.jenetics.internal.util.IntRef;
06
07 import org.jenetics.Chromosome;
08 import org.jenetics.Gene;
09 import org.jenetics.Genotype;
10 import org.jenetics.Mutator;
11 import org.jenetics.Phenotype;
12 import org.jenetics.Population;
13 import org.jenetics.util.MSeq;
14
15 /**
16 * Mutator implementation which is part of the
17 * <a href="https://en.wikipedia.org/wiki/Weasel_program">Weasel program</a>
18 * algorithm. The <i>Weasel program</i> is an thought experiment by Richard
19 * Dawkins to illustrate the functioning of the evolution: random <i>mutation</i>
20 * combined with non-random cumulative <i>selection</i>.
21 * <p>
22 * The mutator mutates the genes of <i>every</i> chromosome of <i>every</i>
23 * genotype in the population with the given mutation probability.
24 * </p>
25 * {@link org.jenetics.engine.Engine} setup for the <i>Weasel program:</i>
26 * <pre>{@code
27 * final Engine<CharacterGene, Integer> engine = Engine
28 * .builder(fitness, gtf)
29 * // Set the 'WeaselSelector'.
30 * .selector(new WeaselSelector<>())
31 * // Disable survivors selector.
32 * .offspringFraction(1)
33 * // Set the 'WeaselMutator'.
34 * .alterers(new WeaselMutator<>(0.05))
35 * .build();
36 * }</pre>
37 *
38 * @see <a href="https://en.wikipedia.org/wiki/Weasel_program">Weasel program</a>
39 * @see WeaselSelector
40 *
41 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
42 * @since 3.5
43 * @version 3.5
44 */
45 public class WeaselMutator<
46 G extends Gene<?, G>,
47 C extends Comparable<? super C>
48 >
49 extends Mutator<G, C>
50 {
51
52 public WeaselMutator(final double probability) {
53 super(probability);
54 }
55
56 public WeaselMutator() {
57 this(0.05);
58 }
59
60 @Override
61 public int alter(final Population<G, C> population, final long generation) {
62 final IntRef alterations = new IntRef(0);
63
64 for (int i = 0; i < population.size(); ++i) {
65 final Phenotype<G, C> pt = population.get(i);
66
67 final Genotype<G> gt = pt.getGenotype();
68 final Genotype<G> mgt = mutate(gt, alterations);
69 final Phenotype<G, C> mpt = pt.newInstance(mgt, generation);
70 population.set(i, mpt);
71 }
72
73 return alterations.value;
74 }
75
76 private Genotype<G> mutate(
77 final Genotype<G> genotype,
78 final IntRef alterations
79 ) {
80 final MSeq<Chromosome<G>> chromosomes = genotype.toSeq().copy();
81
82 alterations.value += IntStream.range(0, chromosomes.size())
83 .map(i -> mutate(chromosomes, i, _probability))
84 .sum();
85
86 return Genotype.of(chromosomes);
87 }
88
89 }
|