Alterer.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-6.3.0).
003  * Copyright (c) 2007-2021 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;
021 
022 import static java.util.Objects.requireNonNull;
023 
024 import io.jenetics.util.ISeq;
025 import io.jenetics.util.Seq;
026 
027 /**
028  * The Alterer is responsible for the changing/recombining the Population.
029  * Alterers can be chained by appending a list of alterers with the
030  {@link io.jenetics.engine.Engine.Builder#alterers(Alterer, Alterer[])} method.
031  *
032  <pre>{@code
033  * final Engine<DoubleGene, Double> engine = Engine
034  *     .builder(gtf, ff)
035  *     .alterers(
036  *         new Crossover<>(0.1),
037  *         new Mutator<>(0.05),
038  *         new MeanAlterer<>(0.2))
039  *     .build();
040  * final EvolutionStream<DoubleGene, Double> stream = engine.stream();
041  * }</pre>
042  *
043  * The order of the alterer calls is: Crossover, Mutation and MeanAlterer.
044  *
045  @param <G> the gene type
046  @param <C> the fitness function result type
047  *
048  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
049  @since 1.0
050  @version 4.0
051  */
052 @FunctionalInterface
053 public interface Alterer<
054     extends Gene<?, G>,
055     extends Comparable<? super C>
056 {
057 
058     /**
059      * The default alter probability: 0.2
060      */
061     double DEFAULT_ALTER_PROBABILITY = 0.2;
062 
063     /**
064      * Alters (recombine) a given population. If the {@code population} is empty,
065      * nothing is altered. The altered population is part of the returned
066      * {@code AlterResult} object.
067      *
068      @param population The Population to be altered. If the {@code population}
069      *        is {@code null} or empty, nothing is altered.
070      @param generation the date of birth (generation) of the altered phenotypes.
071      @return the alter-result object, which contains the altered population
072      *         and the alteration count
073      @throws NullPointerException if the given {@code population} is
074      *        {@code null}.
075      */
076     AltererResult<G, C> alter(
077         final Seq<Phenotype<G, C>> population,
078         final long generation
079     );
080 
081     /**
082      * Returns a composed alterer that first applies the {@code before} alterer
083      * to its input, and then applies {@code this} alterer to the result.
084      *
085      @param before the alterer to apply first
086      @return the new composed alterer
087      */
088     default Alterer<G, C> compose(final Alterer<G, C> before) {
089         return of(requireNonNull(before)this);
090     }
091 
092     /**
093      * Returns a composed alterer that applies the {@code this} alterer
094      * to its input, and then applies the {@code after} alterer to the result.
095      *
096      @param after the alterer to apply first
097      @return the new composed alterer
098      */
099     default Alterer<G, C> andThen(final Alterer<G, C> after) {
100         return of(this, requireNonNull(after));
101     }
102 
103     /**
104      * Combine the given alterers.
105      *
106      @param <G> the gene type
107      @param <C> the fitness function result type
108      @param alterers the alterers to combine.
109      @return a new alterer which consists of the given one
110      @throws NullPointerException if one of the alterers is {@code null}.
111      */
112     @SafeVarargs
113     static <G extends Gene<?, G>, C extends Comparable<? super C>>
114     Alterer<G, C> of(final Alterer<G, C>... alterers) {
115         return alterers.length == 0
116             (p, g-> AltererResult.of(p.asISeq())
117             : alterers.length == 1
118                 ? alterers[0]
119                 new CompositeAlterer<>(ISeq.of(alterers));
120     }
121 
122 }