Engine.java
0001 /*
0002  * Java Genetic Algorithm Library (jenetics-4.2.0).
0003  * Copyright (c) 2007-2018 Franz Wilhelmstötter
0004  *
0005  * Licensed under the Apache License, Version 2.0 (the "License");
0006  * you may not use this file except in compliance with the License.
0007  * You may obtain a copy of the License at
0008  *
0009  *      http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  *
0017  * Author:
0018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
0019  */
0020 package io.jenetics.engine;
0021 
0022 import static java.lang.Math.round;
0023 import static java.lang.String.format;
0024 import static java.util.Objects.requireNonNull;
0025 import static io.jenetics.internal.util.require.probability;
0026 
0027 import java.time.Clock;
0028 import java.util.Iterator;
0029 import java.util.Objects;
0030 import java.util.concurrent.CompletableFuture;
0031 import java.util.concurrent.Executor;
0032 import java.util.concurrent.ForkJoinPool;
0033 import java.util.function.Function;
0034 import java.util.function.Predicate;
0035 import java.util.function.Supplier;
0036 import java.util.function.UnaryOperator;
0037 import java.util.stream.Stream;
0038 
0039 import io.jenetics.Alterer;
0040 import io.jenetics.AltererResult;
0041 import io.jenetics.Chromosome;
0042 import io.jenetics.Gene;
0043 import io.jenetics.Genotype;
0044 import io.jenetics.Mutator;
0045 import io.jenetics.Optimize;
0046 import io.jenetics.Phenotype;
0047 import io.jenetics.Selector;
0048 import io.jenetics.SinglePointCrossover;
0049 import io.jenetics.TournamentSelector;
0050 import io.jenetics.internal.util.require;
0051 import io.jenetics.util.Copyable;
0052 import io.jenetics.util.Factory;
0053 import io.jenetics.util.ISeq;
0054 import io.jenetics.util.MSeq;
0055 import io.jenetics.util.NanoClock;
0056 import io.jenetics.util.Seq;
0057 
0058 /**
0059  * Genetic algorithm <em>engine</em> which is the main class. The following
0060  * example shows the main steps in initializing and executing the GA.
0061  *
0062  <pre>{@code
0063  * public class RealFunction {
0064  *    // Definition of the fitness function.
0065  *    private static Double eval(final Genotype<DoubleGene> gt) {
0066  *        final double x = gt.getGene().doubleValue();
0067  *        return cos(0.5 + sin(x))*cos(x);
0068  *    }
0069  *
0070  *    public static void main(String[] args) {
0071  *        // Create/configuring the engine via its builder.
0072  *        final Engine<DoubleGene, Double> engine = Engine
0073  *            .builder(
0074  *                RealFunction::eval,
0075  *                DoubleChromosome.of(0.0, 2.0*PI))
0076  *            .populationSize(500)
0077  *            .optimize(Optimize.MINIMUM)
0078  *            .alterers(
0079  *                new Mutator<>(0.03),
0080  *                new MeanAlterer<>(0.6))
0081  *            .build();
0082  *
0083  *        // Execute the GA (engine).
0084  *        final Phenotype<DoubleGene, Double> result = engine.stream()
0085  *             // Truncate the evolution stream if no better individual could
0086  *             // be found after 5 consecutive generations.
0087  *            .limit(bySteadyFitness(5))
0088  *             // Terminate the evolution after maximal 100 generations.
0089  *            .limit(100)
0090  *            .collect(toBestPhenotype());
0091  *     }
0092  * }
0093  * }</pre>
0094  *
0095  * The architecture allows to decouple the configuration of the engine from the
0096  * execution. The {@code Engine} is configured via the {@code Engine.Builder}
0097  * class and can't be changed after creation. The actual <i>evolution</i> is
0098  * performed by the {@link EvolutionStream}, which is created by the
0099  * {@code Engine}.
0100  *
0101  * @implNote
0102  *     This class is thread safe:
0103  *     No mutable state is maintained by the engine. Therefore it is save to
0104  *     create multiple evolution streams with one engine, which may be actually
0105  *     used in different threads.
0106  *
0107  @see Engine.Builder
0108  @see EvolutionStart
0109  @see EvolutionResult
0110  @see EvolutionStream
0111  @see EvolutionStatistics
0112  @see Codec
0113  *
0114  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0115  @since 3.0
0116  @version 4.1
0117  */
0118 @SuppressWarnings("deprecation")
0119 public final class Engine<
0120     extends Gene<?, G>,
0121     extends Comparable<? super C>
0122 >
0123     implements
0124         Function<EvolutionStart<G, C>, EvolutionResult<G, C>>,
0125         EvolutionStreamable<G, C>,
0126         EvolutionIterable<G, C>
0127 {
0128 
0129     // Problem definition.
0130     private final Function<? super Genotype<G>, ? extends C> _fitnessFunction;
0131     private final Factory<Genotype<G>> _genotypeFactory;
0132 
0133     // Evolution parameters.
0134     private final Function<? super C, ? extends C> _fitnessScaler;
0135     private final Selector<G, C> _survivorsSelector;
0136     private final Selector<G, C> _offspringSelector;
0137     private final Alterer<G, C> _alterer;
0138     private final Predicate<? super Phenotype<G, C>> _validator;
0139     private final Optimize _optimize;
0140     private final int _offspringCount;
0141     private final int _survivorsCount;
0142     private final long _maximalPhenotypeAge;
0143 
0144     // Execution context for concurrent execution of evolving steps.
0145     private final TimedExecutor _executor;
0146     private final Evaluator<G, C> _evaluator;
0147     private final Clock _clock;
0148 
0149     // Additional parameters.
0150     private final int _individualCreationRetries;
0151     private final UnaryOperator<EvolutionResult<G, C>> _mapper;
0152 
0153 
0154     /**
0155      * Create a new GA engine with the given parameters.
0156      *
0157      @param fitnessFunction the fitness function this GA is using.
0158      @param genotypeFactory the genotype factory this GA is working with.
0159      @param fitnessScaler the fitness scaler this GA is using.
0160      @param survivorsSelector the selector used for selecting the survivors
0161      @param offspringSelector the selector used for selecting the offspring
0162      @param alterer the alterer used for altering the offspring
0163      @param validator phenotype validator which can override the default
0164      *        implementation the {@link Phenotype#isValid()} method.
0165      @param optimize the kind of optimization (minimize or maximize)
0166      @param offspringCount the number of the offspring individuals
0167      @param survivorsCount the number of the survivor individuals
0168      @param maximalPhenotypeAge the maximal age of an individual
0169      @param executor the executor used for executing the single evolve steps
0170      @param evaluator the population fitness evaluator
0171      @param clock the clock used for calculating the timing results
0172      @param individualCreationRetries the maximal number of attempts for
0173      *        creating a valid individual.
0174      @throws NullPointerException if one of the arguments is {@code null}
0175      @throws IllegalArgumentException if the given integer values are smaller
0176      *         than one.
0177      */
0178     Engine(
0179         final Function<? super Genotype<G>, ? extends C> fitnessFunction,
0180         final Factory<Genotype<G>> genotypeFactory,
0181         final Function<? super C, ? extends C> fitnessScaler,
0182         final Selector<G, C> survivorsSelector,
0183         final Selector<G, C> offspringSelector,
0184         final Alterer<G, C> alterer,
0185         final Predicate<? super Phenotype<G, C>> validator,
0186         final Optimize optimize,
0187         final int offspringCount,
0188         final int survivorsCount,
0189         final long maximalPhenotypeAge,
0190         final Executor executor,
0191         final Evaluator<G, C> evaluator,
0192         final Clock clock,
0193         final int individualCreationRetries,
0194         final UnaryOperator<EvolutionResult<G, C>> mapper
0195     ) {
0196         _fitnessFunction = requireNonNull(fitnessFunction);
0197         _fitnessScaler = requireNonNull(fitnessScaler);
0198         _genotypeFactory = requireNonNull(genotypeFactory);
0199         _survivorsSelector = requireNonNull(survivorsSelector);
0200         _offspringSelector = requireNonNull(offspringSelector);
0201         _alterer = requireNonNull(alterer);
0202         _validator = requireNonNull(validator);
0203         _optimize = requireNonNull(optimize);
0204 
0205         _offspringCount = require.nonNegative(offspringCount);
0206         _survivorsCount = require.nonNegative(survivorsCount);
0207         _maximalPhenotypeAge = require.positive(maximalPhenotypeAge);
0208 
0209         _executor = new TimedExecutor(requireNonNull(executor));
0210         _evaluator = requireNonNull(evaluator);
0211         _clock = requireNonNull(clock);
0212 
0213         if (individualCreationRetries < 0) {
0214             throw new IllegalArgumentException(format(
0215                 "Retry count must not be negative: %d",
0216                 individualCreationRetries
0217             ));
0218         }
0219         _individualCreationRetries = individualCreationRetries;
0220         _mapper = requireNonNull(mapper);
0221     }
0222 
0223     /**
0224      * Perform one evolution step with the given {@code population} and
0225      * {@code generation}. New phenotypes are created with the fitness function
0226      * and fitness scaler defined by this <em>engine</em>
0227      <p>
0228      <em>This method is thread-safe.</em>
0229      *
0230      @see #evolve(EvolutionStart)
0231      *
0232      @param population the population to evolve
0233      @param generation the current generation; used for calculating the
0234      *        phenotype age.
0235      @return the evolution result
0236      @throws java.lang.NullPointerException if the given {@code population} is
0237      *         {@code null}
0238      @throws IllegalArgumentException if the given {@code generation} is
0239      *         smaller then one
0240      */
0241     public EvolutionResult<G, C> evolve(
0242         final ISeq<Phenotype<G, C>> population,
0243         final long generation
0244     ) {
0245         return evolve(EvolutionStart.of(population, generation));
0246     }
0247 
0248     /**
0249      * Perform one evolution step with the given evolution {@code start} object
0250      * New phenotypes are created with the fitness function and fitness scaler
0251      * defined by this <em>engine</em>
0252      <p>
0253      <em>This method is thread-safe.</em>
0254      *
0255      @since 3.1
0256      @see #evolve(ISeq, long)
0257      *
0258      @param start the evolution start object
0259      @return the evolution result
0260      @throws java.lang.NullPointerException if the given evolution
0261      *         {@code start} is {@code null}
0262      */
0263     public EvolutionResult<G, C> evolve(final EvolutionStart<G, C> start) {
0264         final Timer timer = Timer.of(_clock).start();
0265 
0266         // Initial evaluation of the population.
0267         final Timer evaluateTimer = Timer.of(_clock).start();
0268         final ISeq<Phenotype<G, C>> evalPop =
0269             _evaluator.evaluate(start.getPopulation());
0270 
0271         if (start.getPopulation().size() != evalPop.size()) {
0272             throw new IllegalStateException(format(
0273                 "Expected %d individuals, but got %d. " +
0274                 "Check your evaluator function.",
0275                 start.getPopulation().size(), evalPop.size()
0276             ));
0277         }
0278 
0279         evaluateTimer.stop();
0280 
0281         // Select the offspring population.
0282         final CompletableFuture<TimedResult<ISeq<Phenotype<G, C>>>> offspring =
0283             _executor.async(() ->
0284                 selectOffspring(evalPop),
0285                 _clock
0286             );
0287 
0288         // Select the survivor population.
0289         final CompletableFuture<TimedResult<ISeq<Phenotype<G, C>>>> survivors =
0290             _executor.async(() ->
0291                 selectSurvivors(evalPop),
0292                 _clock
0293             );
0294 
0295         // Altering the offspring population.
0296         final CompletableFuture<TimedResult<AltererResult<G, C>>> alteredOffspring =
0297             _executor.thenApply(offspring, p ->
0298                 _alterer.alter(p.result, start.getGeneration()),
0299                 _clock
0300             );
0301 
0302         // Filter and replace invalid and old survivor individuals.
0303         final CompletableFuture<TimedResult<FilterResult<G, C>>> filteredSurvivors =
0304             _executor.thenApply(survivors, pop ->
0305                 filter(pop.result, start.getGeneration()),
0306                 _clock
0307             );
0308 
0309         // Filter and replace invalid and old offspring individuals.
0310         final CompletableFuture<TimedResult<FilterResult<G, C>>> filteredOffspring =
0311             _executor.thenApply(alteredOffspring, pop ->
0312                 filter(pop.result.getPopulation(), start.getGeneration()),
0313                 _clock
0314             );
0315 
0316         // Combining survivors and offspring to the new population.
0317         final CompletableFuture<ISeq<Phenotype<G, C>>> population =
0318             filteredSurvivors.thenCombineAsync(filteredOffspring, (s, o->
0319                     ISeq.of(s.result.population.append(o.result.population)),
0320                 _executor.get()
0321             );
0322 
0323         // Evaluate the fitness-function and wait for result.
0324         final ISeq<Phenotype<G, C>> pop = population.join();
0325         final TimedResult<ISeq<Phenotype<G, C>>> result = TimedResult
0326             .of(() -> _evaluator.evaluate(pop), _clock)
0327             .get();
0328 
0329 
0330         final EvolutionDurations durations = EvolutionDurations.of(
0331             offspring.join().duration,
0332             survivors.join().duration,
0333             alteredOffspring.join().duration,
0334             filteredOffspring.join().duration,
0335             filteredSurvivors.join().duration,
0336             result.duration.plus(evaluateTimer.getTime()),
0337             timer.stop().getTime()
0338         );
0339 
0340         final int killCount =
0341             filteredOffspring.join().result.killCount +
0342             filteredSurvivors.join().result.killCount;
0343 
0344         final int invalidCount =
0345             filteredOffspring.join().result.invalidCount +
0346             filteredSurvivors.join().result.invalidCount;
0347 
0348         return _mapper.apply(
0349             EvolutionResult.of(
0350                 _optimize,
0351                 result.result,
0352                 start.getGeneration(),
0353                 durations,
0354                 killCount,
0355                 invalidCount,
0356                 alteredOffspring.join().result.getAlterations()
0357             )
0358         );
0359     }
0360 
0361     /**
0362      * This method is an <i>alias</i> for the {@link #evolve(EvolutionStart)}
0363      * method.
0364      *
0365      @since 3.1
0366      */
0367     @Override
0368     public EvolutionResult<G, C> apply(final EvolutionStart<G, C> start) {
0369         return evolve(start);
0370     }
0371 
0372     // Selects the survivors population. A new population object is returned.
0373     private ISeq<Phenotype<G, C>>
0374     selectSurvivors(final ISeq<Phenotype<G, C>> population) {
0375         return _survivorsCount > 0
0376             ?_survivorsSelector.select(population, _survivorsCount, _optimize)
0377             : ISeq.empty();
0378     }
0379 
0380     // Selects the offspring population. A new population object is returned.
0381     private ISeq<Phenotype<G, C>>
0382     selectOffspring(final ISeq<Phenotype<G, C>> population) {
0383         return _offspringCount > 0
0384             ? _offspringSelector.select(population, _offspringCount, _optimize)
0385             : ISeq.empty();
0386     }
0387 
0388     // Filters out invalid and old individuals. Filtering is done in place.
0389     private FilterResult<G, C> filter(
0390         final Seq<Phenotype<G, C>> population,
0391         final long generation
0392     ) {
0393         int killCount = 0;
0394         int invalidCount = 0;
0395 
0396         final MSeq<Phenotype<G, C>> pop = MSeq.of(population);
0397         for (int i = 0, n = pop.size(); i < n; ++i) {
0398             final Phenotype<G, C> individual = pop.get(i);
0399 
0400             if (!_validator.test(individual)) {
0401                 pop.set(i, newPhenotype(generation));
0402                 ++invalidCount;
0403             else if (individual.getAge(generation> _maximalPhenotypeAge) {
0404                 pop.set(i, newPhenotype(generation));
0405                 ++killCount;
0406             }
0407         }
0408 
0409         return new FilterResult<>(pop.toISeq(), killCount, invalidCount);
0410     }
0411 
0412     // Create a new and valid phenotype
0413     private Phenotype<G, C> newPhenotype(final long generation) {
0414         int count = 0;
0415         Phenotype<G, C> phenotype;
0416         do {
0417             phenotype = Phenotype.of(
0418                 _genotypeFactory.newInstance(),
0419                 generation,
0420                 _fitnessFunction,
0421                 _fitnessScaler
0422             );
0423         while (++count < _individualCreationRetries &&
0424                 !_validator.test(phenotype));
0425 
0426         return phenotype;
0427     }
0428 
0429 
0430     /* *************************************************************************
0431      * Evolution Stream/Iterator creation.
0432      **************************************************************************/
0433 
0434     @Deprecated
0435     @Override
0436     public Iterator<EvolutionResult<G, C>>
0437     iterator(final Supplier<EvolutionStart<G, C>> start) {
0438         return new EvolutionIterator<>(evolutionStart(start)this::evolve);
0439     }
0440 
0441     @Deprecated
0442     @Override
0443     public Iterator<EvolutionResult<G, C>> iterator(final EvolutionInit<G> init) {
0444         return iterator(evolutionStart(init));
0445     }
0446 
0447     @Override
0448     public EvolutionStream<G, C>
0449     stream(final Supplier<EvolutionStart<G, C>> start) {
0450         return EvolutionStream.of(evolutionStart(start)this::evolve);
0451     }
0452 
0453     @Override
0454     public EvolutionStream<G, C> stream(final EvolutionInit<G> init) {
0455         return stream(evolutionStart(init));
0456     }
0457 
0458     private Supplier<EvolutionStart<G, C>>
0459     evolutionStart(final Supplier<EvolutionStart<G, C>> start) {
0460         return () -> {
0461             final EvolutionStart<G, C> es = start.get();
0462             final ISeq<Phenotype<G, C>> population = es.getPopulation();
0463             final long generation = es.getGeneration();
0464 
0465             final Stream<Phenotype<G, C>> stream = Stream.concat(
0466                 population.stream().map(this::toFixedPhenotype),
0467                 Stream.generate(() -> newPhenotype(generation))
0468             );
0469 
0470             final ISeq<Phenotype<G, C>> pop = stream
0471                 .limit(getPopulationSize())
0472                 .collect(ISeq.toISeq());
0473 
0474             return EvolutionStart.of(pop, generation);
0475         };
0476     }
0477 
0478     private Phenotype<G, C> toFixedPhenotype(final Phenotype<G, C> pt) {
0479         return
0480             pt.getFitnessFunction() == _fitnessFunction &&
0481             pt.getFitnessScaler() == _fitnessScaler
0482                 ? pt
0483                 : pt.newInstance(
0484                     pt.getGeneration(),
0485                     _fitnessFunction,
0486                     _fitnessScaler
0487                 );
0488     }
0489 
0490     private Supplier<EvolutionStart<G, C>>
0491     evolutionStart(final EvolutionInit<G> init) {
0492         return evolutionStart(() -> EvolutionStart.of(
0493             init.getPopulation()
0494                 .map(gt -> Phenotype.of(
0495                     gt,
0496                     init.getGeneration(),
0497                     _fitnessFunction,
0498                     _fitnessScaler)
0499                 ),
0500             init.getGeneration())
0501         );
0502     }
0503 
0504     /* *************************************************************************
0505      * Property access methods.
0506      **************************************************************************/
0507 
0508     /**
0509      * Return the fitness function of the GA engine.
0510      *
0511      @return the fitness function
0512      */
0513     public Function<? super Genotype<G>, ? extends C> getFitnessFunction() {
0514         return _fitnessFunction;
0515     }
0516 
0517     /**
0518      * Return the fitness scaler of the GA engine.
0519      *
0520      @return the fitness scaler
0521      */
0522     public Function<? super C, ? extends C> getFitnessScaler() {
0523         return _fitnessScaler;
0524     }
0525 
0526     /**
0527      * Return the used genotype {@link Factory} of the GA. The genotype factory
0528      * is used for creating the initial population and new, random individuals
0529      * when needed (as replacement for invalid and/or died genotypes).
0530      *
0531      @return the used genotype {@link Factory} of the GA.
0532      */
0533     public Factory<Genotype<G>> getGenotypeFactory() {
0534         return _genotypeFactory;
0535     }
0536 
0537     /**
0538      * Return the used survivor {@link Selector} of the GA.
0539      *
0540      @return the used survivor {@link Selector} of the GA.
0541      */
0542     public Selector<G, C> getSurvivorsSelector() {
0543         return _survivorsSelector;
0544     }
0545 
0546     /**
0547      * Return the used offspring {@link Selector} of the GA.
0548      *
0549      @return the used offspring {@link Selector} of the GA.
0550      */
0551     public Selector<G, C> getOffspringSelector() {
0552         return _offspringSelector;
0553     }
0554 
0555     /**
0556      * Return the used {@link Alterer} of the GA.
0557      *
0558      @return the used {@link Alterer} of the GA.
0559      */
0560     public Alterer<G, C> getAlterer() {
0561         return _alterer;
0562     }
0563 
0564     /**
0565      * Return the number of selected offsprings.
0566      *
0567      @return the number of selected offsprings
0568      */
0569     public int getOffspringCount() {
0570         return _offspringCount;
0571     }
0572 
0573     /**
0574      * The number of selected survivors.
0575      *
0576      @return the number of selected survivors
0577      */
0578     public int getSurvivorsCount() {
0579         return _survivorsCount;
0580     }
0581 
0582     /**
0583      * Return the number of individuals of a population.
0584      *
0585      @return the number of individuals of a population
0586      */
0587     public int getPopulationSize() {
0588         return _offspringCount + _survivorsCount;
0589     }
0590 
0591     /**
0592      * Return the maximal allowed phenotype age.
0593      *
0594      @return the maximal allowed phenotype age
0595      */
0596     public long getMaximalPhenotypeAge() {
0597         return _maximalPhenotypeAge;
0598     }
0599 
0600     /**
0601      * Return the optimization strategy.
0602      *
0603      @return the optimization strategy
0604      */
0605     public Optimize getOptimize() {
0606         return _optimize;
0607     }
0608 
0609     /**
0610      * Return the {@link Clock} the engine is using for measuring the execution
0611      * time.
0612      *
0613      @return the clock used for measuring the execution time
0614      */
0615     public Clock getClock() {
0616         return _clock;
0617     }
0618 
0619     /**
0620      * Return the {@link Executor} the engine is using for executing the
0621      * evolution steps.
0622      *
0623      @return the executor used for performing the evolution steps
0624      */
0625     public Executor getExecutor() {
0626         return _executor.get();
0627     }
0628 
0629 
0630     /**
0631      * Return the maximal number of attempt before the {@code Engine} gives
0632      * up creating a valid individual ({@code Phenotype}).
0633      *
0634      @since 4.0
0635      *
0636      @return the maximal number of {@code Phenotype} creation attempts
0637      */
0638     public int getIndividualCreationRetries() {
0639         return _individualCreationRetries;
0640     }
0641 
0642     /**
0643      * Return the evolution result mapper.
0644      *
0645      @since 4.0
0646      *
0647      @return the evolution result mapper
0648      */
0649     public UnaryOperator<EvolutionResult<G, C>> getMapper() {
0650         return _mapper;
0651     }
0652 
0653     /* *************************************************************************
0654      * Builder methods.
0655      **************************************************************************/
0656 
0657     /**
0658      * Create a new evolution {@code Engine.Builder} initialized with the values
0659      * of the current evolution {@code Engine}. With this method, the evolution
0660      * engine can serve as a template for a new one.
0661      *
0662      @return a new engine builder
0663      */
0664     public Builder<G, C> builder() {
0665         return new Builder<G, C>(_genotypeFactory, _fitnessFunction)
0666             .alterers(_alterer)
0667             .clock(_clock)
0668             .evaluator(_evaluator)
0669             .executor(_executor.get())
0670             .fitnessScaler(_fitnessScaler)
0671             .maximalPhenotypeAge(_maximalPhenotypeAge)
0672             .offspringFraction((double)_offspringCount/(double)getPopulationSize())
0673             .offspringSelector(_offspringSelector)
0674             .optimize(_optimize)
0675             .phenotypeValidator(_validator)
0676             .populationSize(getPopulationSize())
0677             .survivorsSelector(_survivorsSelector)
0678             .individualCreationRetries(_individualCreationRetries)
0679             .mapping(_mapper);
0680     }
0681 
0682     /**
0683      * Create a new evolution {@code Engine.Builder} for the given
0684      {@link Problem}.
0685      *
0686      @since 3.4
0687      *
0688      @param problem the problem to be solved by the evolution {@code Engine}
0689      @param <T> the (<i>native</i>) argument type of the problem fitness function
0690      @param <G> the gene type the evolution engine is working with
0691      @param <C> the result type of the fitness function
0692      @return Create a new evolution {@code Engine.Builder}
0693      */
0694     public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
0695     Builder<G, C> builder(final Problem<T, G, C> problem) {
0696         return builder(problem.fitness(), problem.codec());
0697     }
0698 
0699     /**
0700      * Create a new evolution {@code Engine.Builder} with the given fitness
0701      * function and genotype factory.
0702      *
0703      @param ff the fitness function
0704      @param genotypeFactory the genotype factory
0705      @param <G> the gene type
0706      @param <C> the fitness function result type
0707      @return a new engine builder
0708      @throws java.lang.NullPointerException if one of the arguments is
0709      *         {@code null}.
0710      */
0711     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0712     Builder<G, C> builder(
0713         final Function<? super Genotype<G>, ? extends C> ff,
0714         final Factory<Genotype<G>> genotypeFactory
0715     ) {
0716         return new Builder<>(genotypeFactory, ff);
0717     }
0718 
0719     /**
0720      * Create a new evolution {@code Engine.Builder} with the given fitness
0721      * function and chromosome templates.
0722      *
0723      @param ff the fitness function
0724      @param chromosome the first chromosome
0725      @param chromosomes the chromosome templates
0726      @param <G> the gene type
0727      @param <C> the fitness function result type
0728      @return a new engine builder
0729      @throws java.lang.NullPointerException if one of the arguments is
0730      *         {@code null}.
0731      */
0732     @SafeVarargs
0733     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0734     Builder<G, C> builder(
0735         final Function<? super Genotype<G>, ? extends C> ff,
0736         final Chromosome<G> chromosome,
0737         final Chromosome<G>... chromosomes
0738     ) {
0739         return new Builder<>(Genotype.of(chromosome, chromosomes), ff);
0740     }
0741 
0742     /**
0743      * Create a new evolution {@code Engine.Builder} with the given fitness
0744      * function and problem {@code codec}.
0745      *
0746      @since 3.2
0747      *
0748      @param ff the fitness function
0749      @param codec the problem codec
0750      @param <T> the fitness function input type
0751      @param <C> the fitness function result type
0752      @param <G> the gene type
0753      @return a new engine builder
0754      @throws java.lang.NullPointerException if one of the arguments is
0755      *         {@code null}.
0756      */
0757     public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
0758     Builder<G, C> builder(
0759         final Function<? super T, ? extends C> ff,
0760         final Codec<T, G> codec
0761     ) {
0762         return builder(ff.compose(codec.decoder()), codec.encoding());
0763     }
0764 
0765 
0766     /* *************************************************************************
0767      * Inner classes
0768      **************************************************************************/
0769 
0770 
0771     /**
0772      * This interface allows to define different strategies for evaluating the
0773      * fitness functions of a given population. <em>Normally</em>, there is no
0774      * need for <em>overriding</em> the default evaluation strategy, but it might
0775      * be necessary if you have performance problems and a <em>batched</em>
0776      * fitness evaluation would solve the problem.
0777      <p>
0778      * The implementer is free to do the evaluation <em>in place</em>, or create
0779      * new {@link Phenotype} instance and return the newly created one. A simple
0780      * serial evaluator can easily implemented:
0781      *
0782      <pre>{@code
0783      * final Evaluator<G, C> evaluator = population -> {
0784      *     population.forEach(Phenotype::evaluate);
0785      *     return population.asISeq();
0786      * };
0787      * }</pre>
0788      *
0789      * @implSpec
0790      * The size of the returned, evaluated, phenotype sequence must be exactly
0791      * the size of the input phenotype sequence. It is allowed to return the
0792      * input sequence, after evaluation, as well a newly created one.
0793      *
0794      * @apiNote
0795      * This interface is an <em>advanced</em> {@code Engine} configuration
0796      * feature, which should be only used when there is a performance gain from
0797      * implementing a different evaluation strategy. Another use case is, when
0798      * the fitness value of an individual also depends on the current composition
0799      * of the population.
0800      *
0801      @see GenotypeEvaluator
0802      @see Engine.Builder#evaluator(Engine.Evaluator)
0803      *
0804      @param <G> the gene type
0805      @param <C> the fitness result type
0806      *
0807      @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0808      @version 4.2
0809      @since 4.2
0810      */
0811     @FunctionalInterface
0812     public static interface Evaluator<
0813         extends Gene<?, G>,
0814         extends Comparable<? super C>
0815     {
0816 
0817         /**
0818          * Evaluates the fitness values of the given {@code population}. The
0819          * given {@code population} might contain already evaluated individuals.
0820          * It is the responsibility of the implementer to filter out already
0821          * evaluated individuals, if desired.
0822          *
0823          @param population the population to evaluate
0824          @return the evaluated population. Implementers are free to return the
0825          *         the input population or a newly created one.
0826          */
0827         public ISeq<Phenotype<G, C>> evaluate(final Seq<Phenotype<G, C>> population);
0828 
0829         /**
0830          * Create a new phenotype evaluator from a given genotype {@code evaluator}.
0831          *
0832          * @implNote
0833          * The returned {@link Evaluator} will only forward <em>un</em>-evaluated
0834          * individuals to the given genotype {@code evaluator}. This means, that
0835          * already evaluated individuals are filtered from the population, which
0836          * is then forwarded to the underlying genotype {@code evaluator}.
0837          *
0838          @param evaluator the genotype evaluator
0839          @param <G> the gene type
0840          @param <C> the fitness result type
0841          @return <em>normal</em> phenotype evaluator from the given genotype
0842          *         evaluator
0843          @throws NullPointerException if the given {@code evaluator} is
0844          *         {@code null}
0845          */
0846         public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0847         Evaluator<G, C> of(final GenotypeEvaluator<G, C> evaluator) {
0848             requireNonNull(evaluator);
0849 
0850             return population -> {
0851                 final ISeq<Genotype<G>> genotypes = population.stream()
0852                     .filter(pt -> !pt.isEvaluated())
0853                     .map(Phenotype::getGenotype)
0854                     .collect(ISeq.toISeq());
0855 
0856                 if (genotypes.nonEmpty()) {
0857                     final ISeq<C> results = evaluator.evaluate(
0858                         genotypes,
0859                         population.get(0).getFitnessFunction()
0860                     );
0861 
0862                     if (genotypes.size() != results.size()) {
0863                         throw new IllegalStateException(format(
0864                             "Expected %d results, but got %d. " +
0865                             "Check your evaluator function.",
0866                             genotypes.size(), results.size()
0867                         ));
0868                     }
0869 
0870                     final MSeq<Phenotype<G, C>> evaluated = population.asMSeq();
0871                     for (int i = 0, j = 0; i < evaluated.length(); ++i) {
0872                         if (!population.get(i).isEvaluated()) {
0873                             evaluated.set(
0874                                 i,
0875                                 population.get(i).withFitness(results.get(j++))
0876                             );
0877                         }
0878                     }
0879 
0880                     return evaluated.toISeq();
0881                 else {
0882                     return population.asISeq();
0883                 }
0884             };
0885         }
0886 
0887     }
0888 
0889     /**
0890      * This interface gives a different possibility in evaluating the fitness
0891      * values of a population. Sometimes it is necessary (mostly for performance
0892      * reason) to calculate the fitness for the whole population at once. This
0893      * interface allows you to do so. A simple serial evaluator can easily
0894      * implemented:
0895      *
0896      <pre>{@code
0897      * final GenotypeEvaluator<G, C> gte = (g, f) -> g.map(f).asISeq()
0898      * final Evaluator<G, C> evaluator = Evaluator.of(gte);
0899      * }</pre>
0900      *
0901      * @implSpec
0902      * The size of the returned result sequence must be exactly the size of the
0903      * input genotype sequence.
0904      *
0905      * @apiNote
0906      * This interface is an <em>advanced</em> {@code Engine} configuration
0907      * feature, which should be only used when there is a performance gain from
0908      * implementing a different evaluation strategy.
0909      *
0910      @see Evaluator
0911      @see Engine.Builder#evaluator(Engine.GenotypeEvaluator)
0912      *
0913      @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0914      @version 4.2
0915      @since 4.2
0916      */
0917     @FunctionalInterface
0918     public static interface GenotypeEvaluator<
0919         extends Gene<?, G>,
0920         extends Comparable<? super C>
0921     {
0922 
0923         /**
0924          * Calculate the fitness values for the given sequence of genotypes.
0925          *
0926          @see Engine.Evaluator#of(Engine.GenotypeEvaluator)
0927          *
0928          @param genotypes the genotypes to evaluate the fitness value for
0929          @param function the fitness function
0930          @return the fitness values for the given {@code genotypes} The length
0931          *         of the fitness result sequence must match with the size of
0932          *         the given {@code genotypes}.
0933          */
0934         public ISeq<C> evaluate(
0935             final Seq<Genotype<G>> genotypes,
0936             final Function<? super Genotype<G>, ? extends C> function
0937         );
0938 
0939     }
0940 
0941 
0942     /**
0943      * Builder class for building GA {@code Engine} instances.
0944      *
0945      @see Engine
0946      *
0947      @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0948      @since 3.0
0949      @version 4.0
0950      */
0951     public static final class Builder<
0952         extends Gene<?, G>,
0953         extends Comparable<? super C>
0954     >
0955         implements Copyable<Builder<G, C>>
0956     {
0957 
0958         // No default values for this properties.
0959         private Function<? super Genotype<G>, ? extends C> _fitnessFunction;
0960         private Factory<Genotype<G>> _genotypeFactory;
0961 
0962         // This are the properties which default values.
0963         private Function<? super C, ? extends C> _fitnessScaler = a -> a;
0964         private Selector<G, C> _survivorsSelector = new TournamentSelector<>(3);
0965         private Selector<G, C> _offspringSelector = new TournamentSelector<>(3);
0966         private Alterer<G, C> _alterer = Alterer.of(
0967             new SinglePointCrossover<G, C>(0.2),
0968             new Mutator<>(0.15)
0969         );
0970         private Predicate<? super Phenotype<G, C>> _validator = Phenotype::isValid;
0971         private Optimize _optimize = Optimize.MAXIMUM;
0972         private double _offspringFraction = 0.6;
0973         private int _populationSize = 50;
0974         private long _maximalPhenotypeAge = 70;
0975 
0976         // Engine execution environment.
0977         private Executor _executor = ForkJoinPool.commonPool();
0978         private Clock _clock = NanoClock.systemUTC();
0979         private Evaluator<G, C> _evaluator;
0980 
0981         private int _individualCreationRetries = 10;
0982         private UnaryOperator<EvolutionResult<G, C>> _mapper = r -> r;
0983 
0984         private Builder(
0985             final Factory<Genotype<G>> genotypeFactory,
0986             final Function<? super Genotype<G>, ? extends C> fitnessFunction
0987         ) {
0988             _genotypeFactory = requireNonNull(genotypeFactory);
0989             _fitnessFunction = requireNonNull(fitnessFunction);
0990         }
0991 
0992         /**
0993          * Set the fitness function of the evolution {@code Engine}.
0994          *
0995          @param function the fitness function to use in the GA {@code Engine}
0996          @return {@code this} builder, for command chaining
0997          */
0998         public Builder<G, C> fitnessFunction(
0999             final Function<? super Genotype<G>, ? extends C> function
1000         ) {
1001             _fitnessFunction = requireNonNull(function);
1002             return this;
1003         }
1004 
1005         /**
1006          * Set the fitness scaler of the evolution {@code Engine}. <i>Default
1007          * value is set to the identity function.</i>
1008          *
1009          @param scaler the fitness scale to use in the GA {@code Engine}
1010          @return {@code this} builder, for command chaining
1011          */
1012         public Builder<G, C> fitnessScaler(
1013             final Function<? super C, ? extends C> scaler
1014         ) {
1015             _fitnessScaler = requireNonNull(scaler);
1016             return this;
1017         }
1018 
1019         /**
1020          * The genotype factory used for creating new individuals.
1021          *
1022          @param genotypeFactory the genotype factory for creating new
1023          *        individuals.
1024          @return {@code this} builder, for command chaining
1025          */
1026         public Builder<G, C> genotypeFactory(
1027             final Factory<Genotype<G>> genotypeFactory
1028         ) {
1029             _genotypeFactory = requireNonNull(genotypeFactory);
1030             return this;
1031         }
1032 
1033         /**
1034          * The selector used for selecting the offspring population. <i>Default
1035          * values is set to {@code TournamentSelector<>(3)}.</i>
1036          *
1037          @param selector used for selecting the offspring population
1038          @return {@code this} builder, for command chaining
1039          */
1040         public Builder<G, C> offspringSelector(
1041             final Selector<G, C> selector
1042         ) {
1043             _offspringSelector = requireNonNull(selector);
1044             return this;
1045         }
1046 
1047         /**
1048          * The selector used for selecting the survivors population. <i>Default
1049          * values is set to {@code TournamentSelector<>(3)}.</i>
1050          *
1051          @param selector used for selecting survivors population
1052          @return {@code this} builder, for command chaining
1053          */
1054         public Builder<G, C> survivorsSelector(
1055             final Selector<G, C> selector
1056         ) {
1057             _survivorsSelector = requireNonNull(selector);
1058             return this;
1059         }
1060 
1061         /**
1062          * The selector used for selecting the survivors and offspring
1063          * population. <i>Default values is set to
1064          * {@code TournamentSelector<>(3)}.</i>
1065          *
1066          @param selector used for selecting survivors and offspring population
1067          @return {@code this} builder, for command chaining
1068          */
1069         public Builder<G, C> selector(final Selector<G, C> selector) {
1070             _offspringSelector = requireNonNull(selector);
1071             _survivorsSelector = requireNonNull(selector);
1072             return this;
1073         }
1074 
1075         /**
1076          * The alterers used for alter the offspring population. <i>Default
1077          * values is set to {@code new SinglePointCrossover<>(0.2)} followed by
1078          * {@code new Mutator<>(0.15)}.</i>
1079          *
1080          @param first the first alterer used for alter the offspring
1081          *        population
1082          @param rest the rest of the alterers used for alter the offspring
1083          *        population
1084          @return {@code this} builder, for command chaining
1085          @throws java.lang.NullPointerException if one of the alterers is
1086          *         {@code null}.
1087          */
1088         @SafeVarargs
1089         public final Builder<G, C> alterers(
1090             final Alterer<G, C> first,
1091             final Alterer<G, C>... rest
1092         ) {
1093             requireNonNull(first);
1094             Stream.of(rest).forEach(Objects::requireNonNull);
1095 
1096             _alterer = rest.length == 0
1097                 ? first
1098                 : Alterer.of(rest).compose(first);
1099 
1100             return this;
1101         }
1102 
1103         /**
1104          * The phenotype validator used for detecting invalid individuals.
1105          * Alternatively it is also possible to set the genotype validator with
1106          {@link #genotypeFactory(Factory)}, which will replace any
1107          * previously set phenotype validators.
1108          *
1109          <p><i>Default value is set to {@code Phenotype::isValid}.</i></p>
1110          *
1111          @since 3.1
1112          *
1113          @see #genotypeValidator(Predicate)
1114          *
1115          @param validator the {@code validator} used for validating the
1116          *        individuals (phenotypes).
1117          @return {@code this} builder, for command chaining
1118          @throws java.lang.NullPointerException if the {@code validator} is
1119          *         {@code null}.
1120          */
1121         public Builder<G, C> phenotypeValidator(
1122             final Predicate<? super Phenotype<G, C>> validator
1123         ) {
1124             _validator = requireNonNull(validator);
1125             return this;
1126         }
1127 
1128         /**
1129          * The genotype validator used for detecting invalid individuals.
1130          * Alternatively it is also possible to set the phenotype validator with
1131          {@link #phenotypeValidator(Predicate)}, which will replace any
1132          * previously set genotype validators.
1133          *
1134          <p><i>Default value is set to {@code Genotype::isValid}.</i></p>
1135          *
1136          @since 3.1
1137          *
1138          @see #phenotypeValidator(Predicate)
1139          *
1140          @param validator the {@code validator} used for validating the
1141          *        individuals (genotypes).
1142          @return {@code this} builder, for command chaining
1143          @throws java.lang.NullPointerException if the {@code validator} is
1144          *         {@code null}.
1145          */
1146         public Builder<G, C> genotypeValidator(
1147             final Predicate<? super Genotype<G>> validator
1148         ) {
1149             requireNonNull(validator);
1150 
1151             _validator = pt -> validator.test(pt.getGenotype());
1152             return this;
1153         }
1154 
1155         /**
1156          * The optimization strategy used by the engine. <i>Default values is
1157          * set to {@code Optimize.MAXIMUM}.</i>
1158          *
1159          @param optimize the optimization strategy used by the engine
1160          @return {@code this} builder, for command chaining
1161          */
1162         public Builder<G, C> optimize(final Optimize optimize) {
1163             _optimize = requireNonNull(optimize);
1164             return this;
1165         }
1166 
1167         /**
1168          * Set to a fitness maximizing strategy.
1169          *
1170          @since 3.4
1171          *
1172          @return {@code this} builder, for command chaining
1173          */
1174         public Builder<G, C> maximizing() {
1175             return optimize(Optimize.MAXIMUM);
1176         }
1177 
1178         /**
1179          * Set to a fitness minimizing strategy.
1180          *
1181          @since 3.4
1182          *
1183          @return {@code this} builder, for command chaining
1184          */
1185         public Builder<G, C> minimizing() {
1186             return optimize(Optimize.MINIMUM);
1187         }
1188 
1189         /**
1190          * The offspring fraction. <i>Default values is set to {@code 0.6}.</i>
1191          * This method call is equivalent to
1192          * {@code survivorsFraction(1 - offspringFraction)} and will override
1193          * any previously set survivors-fraction.
1194          *
1195          @see #survivorsFraction(double)
1196          *
1197          @param fraction the offspring fraction
1198          @return {@code this} builder, for command chaining
1199          @throws java.lang.IllegalArgumentException if the fraction is not
1200          *         within the range [0, 1].
1201          */
1202         public Builder<G, C> offspringFraction(final double fraction) {
1203             _offspringFraction = probability(fraction);
1204             return this;
1205         }
1206 
1207         /**
1208          * The survivors fraction. <i>Default values is set to {@code 0.4}.</i>
1209          * This method call is equivalent to
1210          * {@code offspringFraction(1 - survivorsFraction)} and will override
1211          * any previously set offspring-fraction.
1212          *
1213          @since 3.8
1214          *
1215          @see #offspringFraction(double)
1216          *
1217          @param fraction the survivors fraction
1218          @return {@code this} builder, for command chaining
1219          @throws java.lang.IllegalArgumentException if the fraction is not
1220          *         within the range [0, 1].
1221          */
1222         public Builder<G, C> survivorsFraction(final double fraction) {
1223             _offspringFraction = 1.0 - probability(fraction);
1224             return this;
1225         }
1226 
1227         /**
1228          * The number of offspring individuals.
1229          *
1230          @since 3.8
1231          *
1232          @param size the number of offspring individuals.
1233          @return {@code this} builder, for command chaining
1234          @throws java.lang.IllegalArgumentException if the size is not
1235          *         within the range [0, population-size].
1236          */
1237         public Builder<G, C> offspringSize(final int size) {
1238             if (size < 0) {
1239                 throw new IllegalArgumentException(format(
1240                     "Offspring size must be greater or equal zero, but was %s.",
1241                     size
1242                 ));
1243             }
1244 
1245             return offspringFraction((double)size/(double)_populationSize);
1246         }
1247 
1248         /**
1249          * The number of survivors.
1250          *
1251          @since 3.8
1252          *
1253          @param size the number of survivors.
1254          @return {@code this} builder, for command chaining
1255          @throws java.lang.IllegalArgumentException if the size is not
1256          *         within the range [0, population-size].
1257          */
1258         public Builder<G, C> survivorsSize(final int size) {
1259             if (size < 0) {
1260                 throw new IllegalArgumentException(format(
1261                     "Survivors must be greater or equal zero, but was %s.",
1262                     size
1263                 ));
1264             }
1265 
1266             return survivorsFraction((double)size/(double)_populationSize);
1267         }
1268 
1269         /**
1270          * The number of individuals which form the population. <i>Default
1271          * values is set to {@code 50}.</i>
1272          *
1273          @param size the number of individuals of a population
1274          @return {@code this} builder, for command chaining
1275          @throws java.lang.IllegalArgumentException if {@code size < 1}
1276          */
1277         public Builder<G, C> populationSize(final int size) {
1278             if (size < 1) {
1279                 throw new IllegalArgumentException(format(
1280                     "Population size must be greater than zero, but was %s.",
1281                     size
1282                 ));
1283             }
1284             _populationSize = size;
1285             return this;
1286         }
1287 
1288         /**
1289          * The maximal allowed age of a phenotype. <i>Default values is set to
1290          * {@code 70}.</i>
1291          *
1292          @param age the maximal phenotype age
1293          @return {@code this} builder, for command chaining
1294          @throws java.lang.IllegalArgumentException if {@code age < 1}
1295          */
1296         public Builder<G, C> maximalPhenotypeAge(final long age) {
1297             if (age < 1) {
1298                 throw new IllegalArgumentException(format(
1299                     "Phenotype age must be greater than one, but was %s.", age
1300                 ));
1301             }
1302             _maximalPhenotypeAge = age;
1303             return this;
1304         }
1305 
1306         /**
1307          * The executor used by the engine.
1308          *
1309          @param executor the executor used by the engine
1310          @return {@code this} builder, for command chaining
1311          */
1312         public Builder<G, C> executor(final Executor executor) {
1313             _executor = requireNonNull(executor);
1314             return this;
1315         }
1316 
1317         /**
1318          * The clock used for calculating the execution durations.
1319          *
1320          @param clock the clock used for calculating the execution durations
1321          @return {@code this} builder, for command chaining
1322          */
1323         public Builder<G, C> clock(final Clock clock) {
1324             _clock = requireNonNull(clock);
1325             return this;
1326         }
1327 
1328         /**
1329          * The phenotype evaluator allows to change the evaluation strategy.
1330          * By default, the population is evaluated concurrently using the
1331          * defined {@link Executor} implementation.
1332          *
1333          * @apiNote
1334          * This is an <em>advanced</em> {@code Engine} configuration feature,
1335          * which should be only used when there is a performance gain from
1336          * implementing a different evaluation strategy.
1337          *
1338          @since 4.2
1339          *
1340          @param evaluator the population evaluation strategy
1341          @return {@code this} builder, for command chaining
1342          */
1343         public Builder<G, C> evaluator(final Evaluator<G, C> evaluator) {
1344             _evaluator = requireNonNull(evaluator);
1345             return this;
1346         }
1347 
1348         /**
1349          * Setting the <em>genotype</em> evaluator used for evaluating the
1350          * fitness function of the population.
1351          *
1352          * @apiNote
1353          * This is an <em>advanced</em> {@code Engine} configuration feature,
1354          * which should be only used when there is a performance gain from
1355          * implementing a different evaluation strategy.
1356          *
1357          @since 4.2
1358          *
1359          @param evaluator the genotype evaluator
1360          @return {@code this} builder, for command chaining
1361          */
1362         public Builder<G, C> evaluator(final GenotypeEvaluator<G, C> evaluator) {
1363             _evaluator = Evaluator.of(evaluator);
1364             return this;
1365         }
1366 
1367         /**
1368          * The maximal number of attempt before the {@code Engine} gives up
1369          * creating a valid individual ({@code Phenotype}). <i>Default values is
1370          * set to {@code 10}.</i>
1371          *
1372          @since 3.1
1373          *
1374          @param retries the maximal retry count
1375          @throws IllegalArgumentException if the given retry {@code count} is
1376          *         smaller than zero.
1377          @return {@code this} builder, for command chaining
1378          */
1379         public Builder<G, C> individualCreationRetries(final int retries) {
1380             if (retries < 0) {
1381                 throw new IllegalArgumentException(format(
1382                     "Retry count must not be negative: %d",
1383                     retries
1384                 ));
1385             }
1386             _individualCreationRetries = retries;
1387             return this;
1388         }
1389 
1390         /**
1391          * The result mapper, which allows to change the evolution result after
1392          * each generation.
1393          *
1394          @since 4.0
1395          @see EvolutionResult#toUniquePopulation()
1396          *
1397          @param mapper the evolution result mapper
1398          @return {@code this} builder, for command chaining
1399          @throws NullPointerException if the given {@code resultMapper} is
1400          *         {@code null}
1401          */
1402         public Builder<G, C> mapping(
1403             final Function<
1404                 super EvolutionResult<G, C>,
1405                 EvolutionResult<G, C>
1406             > mapper
1407         ) {
1408             _mapper = requireNonNull(mapper::apply);
1409             return this;
1410         }
1411 
1412         /**
1413          * Builds an new {@code Engine} instance from the set properties.
1414          *
1415          @return an new {@code Engine} instance from the set properties
1416          */
1417         public Engine<G, C> build() {
1418             return new Engine<>(
1419                 _fitnessFunction,
1420                 _genotypeFactory,
1421                 _fitnessScaler,
1422                 _survivorsSelector,
1423                 _offspringSelector,
1424                 _alterer,
1425                 _validator,
1426                 _optimize,
1427                 getOffspringCount(),
1428                 getSurvivorsCount(),
1429                 _maximalPhenotypeAge,
1430                 _executor,
1431                 _evaluator != null
1432                     ? _evaluator
1433                     new ConcurrentEvaluator<>(_executor),
1434                 _clock,
1435                 _individualCreationRetries,
1436                 _mapper
1437             );
1438         }
1439 
1440         private int getSurvivorsCount() {
1441             return _populationSize - getOffspringCount();
1442         }
1443 
1444         private int getOffspringCount() {
1445             return (int)round(_offspringFraction*_populationSize);
1446         }
1447 
1448         /**
1449          * Return the used {@link Alterer} of the GA.
1450          *
1451          @return the used {@link Alterer} of the GA.
1452          */
1453         public Alterer<G, C> getAlterers() {
1454             return _alterer;
1455         }
1456 
1457         /**
1458          * Return the {@link Clock} the engine is using for measuring the execution
1459          * time.
1460          *
1461          @since 3.1
1462          *
1463          @return the clock used for measuring the execution time
1464          */
1465         public Clock getClock() {
1466             return _clock;
1467         }
1468 
1469         /**
1470          * Return the {@link Executor} the engine is using for executing the
1471          * evolution steps.
1472          *
1473          @since 3.1
1474          *
1475          @return the executor used for performing the evolution steps
1476          */
1477         public Executor getExecutor() {
1478             return _executor;
1479         }
1480 
1481         /**
1482          * Return the fitness function of the GA engine.
1483          *
1484          @since 3.1
1485          *
1486          @return the fitness function
1487          */
1488         public Function<? super Genotype<G>, ? extends C> getFitnessFunction() {
1489             return _fitnessFunction;
1490         }
1491 
1492         /**
1493          * Return the fitness scaler of the GA engine.
1494          *
1495          @since 3.1
1496          *
1497          @return the fitness scaler
1498          */
1499         public Function<? super C, ? extends C> getFitnessScaler() {
1500             return _fitnessScaler;
1501         }
1502 
1503         /**
1504          * Return the used genotype {@link Factory} of the GA. The genotype factory
1505          * is used for creating the initial population and new, random individuals
1506          * when needed (as replacement for invalid and/or died genotypes).
1507          *
1508          @since 3.1
1509          *
1510          @return the used genotype {@link Factory} of the GA.
1511          */
1512         public Factory<Genotype<G>> getGenotypeFactory() {
1513             return _genotypeFactory;
1514         }
1515 
1516         /**
1517          * Return the maximal allowed phenotype age.
1518          *
1519          @since 3.1
1520          *
1521          @return the maximal allowed phenotype age
1522          */
1523         public long getMaximalPhenotypeAge() {
1524             return _maximalPhenotypeAge;
1525         }
1526 
1527         /**
1528          * Return the offspring fraction.
1529          *
1530          @return the offspring fraction.
1531          */
1532         public double getOffspringFraction() {
1533             return _offspringFraction;
1534         }
1535 
1536         /**
1537          * Return the used offspring {@link Selector} of the GA.
1538          *
1539          @since 3.1
1540          *
1541          @return the used offspring {@link Selector} of the GA.
1542          */
1543         public Selector<G, C> getOffspringSelector() {
1544             return _offspringSelector;
1545         }
1546 
1547         /**
1548          * Return the used survivor {@link Selector} of the GA.
1549          *
1550          @since 3.1
1551          *
1552          @return the used survivor {@link Selector} of the GA.
1553          */
1554         public Selector<G, C> getSurvivorsSelector() {
1555             return _survivorsSelector;
1556         }
1557 
1558         /**
1559          * Return the optimization strategy.
1560          *
1561          @since 3.1
1562          *
1563          @return the optimization strategy
1564          */
1565         public Optimize getOptimize() {
1566             return _optimize;
1567         }
1568 
1569         /**
1570          * Return the number of individuals of a population.
1571          *
1572          @since 3.1
1573          *
1574          @return the number of individuals of a population
1575          */
1576         public int getPopulationSize() {
1577             return _populationSize;
1578         }
1579 
1580         /**
1581          * Return the maximal number of attempt before the {@code Engine} gives
1582          * up creating a valid individual ({@code Phenotype}).
1583          *
1584          @since 3.1
1585          *
1586          @return the maximal number of {@code Phenotype} creation attempts
1587          */
1588         public int getIndividualCreationRetries() {
1589             return _individualCreationRetries;
1590         }
1591 
1592         /**
1593          * Return the evolution result mapper.
1594          *
1595          @since 4.0
1596          *
1597          @return the evolution result mapper
1598          */
1599         public UnaryOperator<EvolutionResult<G, C>> getMapper() {
1600             return _mapper;
1601         }
1602 
1603         /**
1604          * Create a new builder, with the current configuration.
1605          *
1606          @since 3.1
1607          *
1608          @return a new builder, with the current configuration
1609          */
1610         @Override
1611         public Builder<G, C> copy() {
1612             return new Builder<G, C>(_genotypeFactory, _fitnessFunction)
1613                 .alterers(_alterer)
1614                 .clock(_clock)
1615                 .executor(_executor)
1616                 .evaluator(_evaluator)
1617                 .fitnessScaler(_fitnessScaler)
1618                 .maximalPhenotypeAge(_maximalPhenotypeAge)
1619                 .offspringFraction(_offspringFraction)
1620                 .offspringSelector(_offspringSelector)
1621                 .phenotypeValidator(_validator)
1622                 .optimize(_optimize)
1623                 .populationSize(_populationSize)
1624                 .survivorsSelector(_survivorsSelector)
1625                 .individualCreationRetries(_individualCreationRetries)
1626                 .mapping(_mapper);
1627         }
1628 
1629     }
1630 
1631 }