| 
001 /*002  * Java Genetic Algorithm Library (jenetics-4.3.0).
 003  * Copyright (c) 2007-2018 Franz Wilhelmstötter
 004  *
 005  * Licensed under the Apache License, Version 2.0 (the "License");
 006  * you may not use this file except in compliance with the License.
 007  * You may obtain a copy of the License at
 008  *
 009  *      http://www.apache.org/licenses/LICENSE-2.0
 010  *
 011  * Unless required by applicable law or agreed to in writing, software
 012  * distributed under the License is distributed on an "AS IS" BASIS,
 013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 014  * See the License for the specific language governing permissions and
 015  * limitations under the License.
 016  *
 017  * Author:
 018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
 019  */
 020 package io.jenetics.ext;
 021
 022 import static java.lang.String.format;
 023 import static io.jenetics.internal.util.Hashes.hash;
 024
 025 import java.util.Random;
 026
 027 import io.jenetics.AltererResult;
 028 import io.jenetics.Chromosome;
 029 import io.jenetics.Gene;
 030 import io.jenetics.Genotype;
 031 import io.jenetics.Mutator;
 032 import io.jenetics.MutatorResult;
 033 import io.jenetics.Phenotype;
 034 import io.jenetics.util.ISeq;
 035 import io.jenetics.util.RandomRegistry;
 036 import io.jenetics.util.Seq;
 037
 038 /**
 039  * Mutator implementation which is part of the
 040  * <a href="https://en.wikipedia.org/wiki/Weasel_program">Weasel program</a>
 041  * algorithm. The <i>Weasel program</i> is an thought experiment by Richard
 042  * Dawkins to illustrate the functioning of the evolution: random <i>mutation</i>
 043  * combined with non-random cumulative <i>selection</i>.
 044  * <p>
 045  * The mutator mutates the genes of <i>every</i> chromosome of <i>every</i>
 046  * genotype in the population with the given mutation probability.
 047  * </p>
 048  * {@link io.jenetics.engine.Engine} setup for the <i>Weasel program:</i>
 049  * <pre>{@code
 050  * final Engine<CharacterGene, Integer> engine = Engine
 051  *     .builder(fitness, gtf)
 052  *      // Set the 'WeaselSelector'.
 053  *     .selector(new WeaselSelector<>())
 054  *      // Disable survivors selector.
 055  *     .offspringFraction(1)
 056  *      // Set the 'WeaselMutator'.
 057  *     .alterers(new WeaselMutator<>(0.05))
 058  *     .build();
 059  * }</pre>
 060  *
 061  * @see <a href="https://en.wikipedia.org/wiki/Weasel_program">Weasel program</a>
 062  * @see WeaselSelector
 063  *
 064  * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
 065  * @since 3.5
 066  * @version 3.5
 067  */
 068 public class WeaselMutator<
 069     G extends Gene<?, G>,
 070     C extends Comparable<? super C>
 071 >
 072     extends Mutator<G, C>
 073 {
 074
 075     public WeaselMutator(final double probability) {
 076         super(probability);
 077     }
 078
 079     public WeaselMutator() {
 080         this(0.05);
 081     }
 082
 083     @Override
 084     public AltererResult<G, C>
 085     alter(final Seq<Phenotype<G, C>> population, final long generation) {
 086         final Random random = RandomRegistry.getRandom();
 087         final Seq<MutatorResult<Phenotype<G, C>>> result = population
 088             .map(pt -> mutate(pt, generation, _probability, random));
 089
 090         return AltererResult.of(
 091             result.map(MutatorResult::getResult).asISeq(),
 092             result.stream().mapToInt(MutatorResult::getMutations).sum()
 093         );
 094     }
 095
 096     @Override
 097     protected MutatorResult<Genotype<G>> mutate(
 098         final Genotype<G> genotype,
 099         final double p,
 100         final Random random
 101     ) {
 102         final ISeq<MutatorResult<Chromosome<G>>> result = genotype.toSeq()
 103             .map(gt -> mutate(gt, p, random));
 104
 105         return MutatorResult.of(
 106             Genotype.of(result.map(MutatorResult::getResult)),
 107             result.stream().mapToInt(MutatorResult::getMutations).sum()
 108         );
 109     }
 110
 111     @Override
 112     public int hashCode() {
 113         return hash(_probability);
 114     }
 115
 116     @Override
 117     public boolean equals(final Object obj) {
 118         return obj == this ||
 119             obj instanceof WeaselMutator &&
 120             Double.compare(((WeaselMutator) obj)._probability, _probability) == 0;
 121     }
 122
 123     @Override
 124     public String toString() {
 125         return format("WeaselMutator[%f]", _probability);
 126     }
 127
 128 }
 |