package org.jenetix; import static java.lang.String.format; import static java.util.Objects.requireNonNull; import org.jenetics.Gene; import org.jenetics.Optimize; import org.jenetics.Phenotype; import org.jenetics.Population; import org.jenetics.Selector; import org.jenetics.stat.MinMax; /** * Selector implementation which is part of the * <a href="https://en.wikipedia.org/wiki/Weasel_program">Weasel program</a> * algorithm. The <i>Weasel program</i> is an thought experiment by Richard * Dawkins to illustrate the functioning of the evolution: random <i>mutation</i> * combined with non-random cumulative <i>selection</i>. * <p> * The selector always returns populations which only contains "{@code count}" * instances of the <i>best</i> {@link Phenotype}. * </p> * {@link org.jenetics.engine.Engine} setup for the <i>Weasel program:</i> * <pre>{@code * final Engine<CharacterGene, Integer> engine = Engine * .builder(fitness, gtf) * // Set the 'WeaselSelector'. * .selector(new WeaselSelector<>()) * // Disable survivors selector. * .offspringFraction(1) * // Set the 'WeaselMutator'. * .alterers(new WeaselMutator<>(0.05)) * .build(); * }</pre> * * @see <a href="https://en.wikipedia.org/wiki/Weasel_program">Weasel program</a> * @see WeaselMutator * * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> * @since 3.5 * @version 3.5 */ public class WeaselSelector< G extends Gene<?, G>, C extends Comparable<? super C> > implements Selector<G, C> { @Override public Population<G, C> select( final Population<G, C> population, final int count, final Optimize opt ) { requireNonNull(population, "Population"); requireNonNull(opt, "Optimization"); if (count < 0) { throw new IllegalArgumentException(format( "Selection count must be greater or equal then zero, but was %s", count )); } final MinMax<Phenotype<G, C>> minMax = population.stream() .collect(MinMax.toMinMax(opt.ascending())); return new Population<G, C>(count).fill(minMax::getMax, count); } }