01 package io.jenetics.ext;
02
03 import static java.lang.String.format;
04 import static java.util.Objects.requireNonNull;
05
06 import io.jenetics.Gene;
07 import io.jenetics.Optimize;
08 import io.jenetics.Phenotype;
09 import io.jenetics.Selector;
10 import io.jenetics.stat.MinMax;
11 import io.jenetics.util.ISeq;
12 import io.jenetics.util.MSeq;
13 import io.jenetics.util.Seq;
14
15 /**
16 * Selector 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 selector always returns populations which only contains "{@code count}"
23 * instances of the <i>best</i> {@link Phenotype}.
24 * </p>
25 * {@link io.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 WeaselMutator
40 *
41 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
42 * @since 3.5
43 * @version 3.5
44 */
45 public class WeaselSelector<
46 G extends Gene<?, G>,
47 C extends Comparable<? super C>
48 >
49 implements Selector<G, C>
50 {
51 @Override
52 public ISeq<Phenotype<G, C>> select(
53 final Seq<Phenotype<G, C>> population,
54 final int count,
55 final Optimize opt
56 ) {
57 requireNonNull(population, "Population");
58 requireNonNull(opt, "Optimization");
59 if (count < 0) {
60 throw new IllegalArgumentException(format(
61 "Selection count must be greater or equal then zero, but was %s",
62 count
63 ));
64 }
65
66 final MinMax<Phenotype<G, C>> minMax = population.stream()
67 .collect(MinMax.toMinMax(opt.ascending()));
68
69 final MSeq<Phenotype<G, C>> result = MSeq.ofLength(count);
70 return result.fill(minMax::getMax).toISeq();
71 }
72 }
|