Engine.java
0001 /*
0002  * Java Genetic Algorithm Library (jenetics-4.3.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      @deprecated The fitness scaler will be remove in a future version.
0523      */
0524     @Deprecated
0525     public Function<? super C, ? extends C> getFitnessScaler() {
0526         return _fitnessScaler;
0527     }
0528 
0529     /**
0530      * Return the used genotype {@link Factory} of the GA. The genotype factory
0531      * is used for creating the initial population and new, random individuals
0532      * when needed (as replacement for invalid and/or died genotypes).
0533      *
0534      @return the used genotype {@link Factory} of the GA.
0535      */
0536     public Factory<Genotype<G>> getGenotypeFactory() {
0537         return _genotypeFactory;
0538     }
0539 
0540     /**
0541      * Return the used survivor {@link Selector} of the GA.
0542      *
0543      @return the used survivor {@link Selector} of the GA.
0544      */
0545     public Selector<G, C> getSurvivorsSelector() {
0546         return _survivorsSelector;
0547     }
0548 
0549     /**
0550      * Return the used offspring {@link Selector} of the GA.
0551      *
0552      @return the used offspring {@link Selector} of the GA.
0553      */
0554     public Selector<G, C> getOffspringSelector() {
0555         return _offspringSelector;
0556     }
0557 
0558     /**
0559      * Return the used {@link Alterer} of the GA.
0560      *
0561      @return the used {@link Alterer} of the GA.
0562      */
0563     public Alterer<G, C> getAlterer() {
0564         return _alterer;
0565     }
0566 
0567     /**
0568      * Return the number of selected offsprings.
0569      *
0570      @return the number of selected offsprings
0571      */
0572     public int getOffspringCount() {
0573         return _offspringCount;
0574     }
0575 
0576     /**
0577      * The number of selected survivors.
0578      *
0579      @return the number of selected survivors
0580      */
0581     public int getSurvivorsCount() {
0582         return _survivorsCount;
0583     }
0584 
0585     /**
0586      * Return the number of individuals of a population.
0587      *
0588      @return the number of individuals of a population
0589      */
0590     public int getPopulationSize() {
0591         return _offspringCount + _survivorsCount;
0592     }
0593 
0594     /**
0595      * Return the maximal allowed phenotype age.
0596      *
0597      @return the maximal allowed phenotype age
0598      */
0599     public long getMaximalPhenotypeAge() {
0600         return _maximalPhenotypeAge;
0601     }
0602 
0603     /**
0604      * Return the optimization strategy.
0605      *
0606      @return the optimization strategy
0607      */
0608     public Optimize getOptimize() {
0609         return _optimize;
0610     }
0611 
0612     /**
0613      * Return the {@link Clock} the engine is using for measuring the execution
0614      * time.
0615      *
0616      @return the clock used for measuring the execution time
0617      */
0618     public Clock getClock() {
0619         return _clock;
0620     }
0621 
0622     /**
0623      * Return the {@link Executor} the engine is using for executing the
0624      * evolution steps.
0625      *
0626      @return the executor used for performing the evolution steps
0627      */
0628     public Executor getExecutor() {
0629         return _executor.get();
0630     }
0631 
0632 
0633     /**
0634      * Return the maximal number of attempt before the {@code Engine} gives
0635      * up creating a valid individual ({@code Phenotype}).
0636      *
0637      @since 4.0
0638      *
0639      @return the maximal number of {@code Phenotype} creation attempts
0640      */
0641     public int getIndividualCreationRetries() {
0642         return _individualCreationRetries;
0643     }
0644 
0645     /**
0646      * Return the evolution result mapper.
0647      *
0648      @since 4.0
0649      *
0650      @return the evolution result mapper
0651      */
0652     public UnaryOperator<EvolutionResult<G, C>> getMapper() {
0653         return _mapper;
0654     }
0655 
0656     /* *************************************************************************
0657      * Builder methods.
0658      **************************************************************************/
0659 
0660     /**
0661      * Create a new evolution {@code Engine.Builder} initialized with the values
0662      * of the current evolution {@code Engine}. With this method, the evolution
0663      * engine can serve as a template for a new one.
0664      *
0665      @return a new engine builder
0666      */
0667     public Builder<G, C> builder() {
0668         return new Builder<G, C>(_genotypeFactory, _fitnessFunction)
0669             .alterers(_alterer)
0670             .clock(_clock)
0671             .evaluator(_evaluator)
0672             .executor(_executor.get())
0673             .fitnessScaler(_fitnessScaler)
0674             .maximalPhenotypeAge(_maximalPhenotypeAge)
0675             .offspringFraction((double)_offspringCount/(double)getPopulationSize())
0676             .offspringSelector(_offspringSelector)
0677             .optimize(_optimize)
0678             .phenotypeValidator(_validator)
0679             .populationSize(getPopulationSize())
0680             .survivorsSelector(_survivorsSelector)
0681             .individualCreationRetries(_individualCreationRetries)
0682             .mapping(_mapper);
0683     }
0684 
0685     /**
0686      * Create a new evolution {@code Engine.Builder} for the given
0687      {@link Problem}.
0688      *
0689      @since 3.4
0690      *
0691      @param problem the problem to be solved by the evolution {@code Engine}
0692      @param <T> the (<i>native</i>) argument type of the problem fitness function
0693      @param <G> the gene type the evolution engine is working with
0694      @param <C> the result type of the fitness function
0695      @return Create a new evolution {@code Engine.Builder}
0696      */
0697     public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
0698     Builder<G, C> builder(final Problem<T, G, C> problem) {
0699         return builder(problem.fitness(), problem.codec());
0700     }
0701 
0702     /**
0703      * Create a new evolution {@code Engine.Builder} with the given fitness
0704      * function and genotype factory.
0705      *
0706      @param ff the fitness function
0707      @param genotypeFactory the genotype factory
0708      @param <G> the gene type
0709      @param <C> the fitness function result type
0710      @return a new engine builder
0711      @throws java.lang.NullPointerException if one of the arguments is
0712      *         {@code null}.
0713      */
0714     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0715     Builder<G, C> builder(
0716         final Function<? super Genotype<G>, ? extends C> ff,
0717         final Factory<Genotype<G>> genotypeFactory
0718     ) {
0719         return new Builder<>(genotypeFactory, ff);
0720     }
0721 
0722     /**
0723      * Create a new evolution {@code Engine.Builder} with the given fitness
0724      * function and chromosome templates.
0725      *
0726      @param ff the fitness function
0727      @param chromosome the first chromosome
0728      @param chromosomes the chromosome templates
0729      @param <G> the gene type
0730      @param <C> the fitness function result type
0731      @return a new engine builder
0732      @throws java.lang.NullPointerException if one of the arguments is
0733      *         {@code null}.
0734      */
0735     @SafeVarargs
0736     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0737     Builder<G, C> builder(
0738         final Function<? super Genotype<G>, ? extends C> ff,
0739         final Chromosome<G> chromosome,
0740         final Chromosome<G>... chromosomes
0741     ) {
0742         return new Builder<>(Genotype.of(chromosome, chromosomes), ff);
0743     }
0744 
0745     /**
0746      * Create a new evolution {@code Engine.Builder} with the given fitness
0747      * function and problem {@code codec}.
0748      *
0749      @since 3.2
0750      *
0751      @param ff the fitness function
0752      @param codec the problem codec
0753      @param <T> the fitness function input type
0754      @param <C> the fitness function result type
0755      @param <G> the gene type
0756      @return a new engine builder
0757      @throws java.lang.NullPointerException if one of the arguments is
0758      *         {@code null}.
0759      */
0760     public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
0761     Builder<G, C> builder(
0762         final Function<? super T, ? extends C> ff,
0763         final Codec<T, G> codec
0764     ) {
0765         return builder(ff.compose(codec.decoder()), codec.encoding());
0766     }
0767 
0768 
0769     /* *************************************************************************
0770      * Inner classes
0771      **************************************************************************/
0772 
0773 
0774     /**
0775      * This interface allows to define different strategies for evaluating the
0776      * fitness functions of a given population. <em>Normally</em>, there is no
0777      * need for <em>overriding</em> the default evaluation strategy, but it might
0778      * be necessary if you have performance problems and a <em>batched</em>
0779      * fitness evaluation would solve the problem.
0780      <p>
0781      * The implementer is free to do the evaluation <em>in place</em>, or create
0782      * new {@link Phenotype} instance and return the newly created one. A simple
0783      * serial evaluator can easily implemented:
0784      *
0785      <pre>{@code
0786      * final Evaluator<G, C> evaluator = population -> {
0787      *     population.forEach(Phenotype::evaluate);
0788      *     return population.asISeq();
0789      * };
0790      * }</pre>
0791      *
0792      * @implSpec
0793      * The size of the returned, evaluated, phenotype sequence must be exactly
0794      * the size of the input phenotype sequence. It is allowed to return the
0795      * input sequence, after evaluation, as well a newly created one.
0796      *
0797      * @apiNote
0798      * This interface is an <em>advanced</em> {@code Engine} configuration
0799      * feature, which should be only used when there is a performance gain from
0800      * implementing a different evaluation strategy. Another use case is, when
0801      * the fitness value of an individual also depends on the current composition
0802      * of the population.
0803      *
0804      @see GenotypeEvaluator
0805      @see Engine.Builder#evaluator(Engine.Evaluator)
0806      *
0807      @param <G> the gene type
0808      @param <C> the fitness result type
0809      *
0810      @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0811      @version 4.2
0812      @since 4.2
0813      */
0814     @FunctionalInterface
0815     public static interface Evaluator<
0816         extends Gene<?, G>,
0817         extends Comparable<? super C>
0818     {
0819 
0820         /**
0821          * Evaluates the fitness values of the given {@code population}. The
0822          * given {@code population} might contain already evaluated individuals.
0823          * It is the responsibility of the implementer to filter out already
0824          * evaluated individuals, if desired.
0825          *
0826          @param population the population to evaluate
0827          @return the evaluated population. Implementers are free to return the
0828          *         the input population or a newly created one.
0829          */
0830         public ISeq<Phenotype<G, C>> evaluate(final Seq<Phenotype<G, C>> population);
0831 
0832         /**
0833          * Create a new phenotype evaluator from a given genotype {@code evaluator}.
0834          *
0835          * @implNote
0836          * The returned {@link Evaluator} will only forward <em>un</em>-evaluated
0837          * individuals to the given genotype {@code evaluator}. This means, that
0838          * already evaluated individuals are filtered from the population, which
0839          * is then forwarded to the underlying genotype {@code evaluator}.
0840          *
0841          @param evaluator the genotype evaluator
0842          @param <G> the gene type
0843          @param <C> the fitness result type
0844          @return <em>normal</em> phenotype evaluator from the given genotype
0845          *         evaluator
0846          @throws NullPointerException if the given {@code evaluator} is
0847          *         {@code null}
0848          */
0849         public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0850         Evaluator<G, C> of(final GenotypeEvaluator<G, C> evaluator) {
0851             requireNonNull(evaluator);
0852 
0853             return population -> {
0854                 final ISeq<Genotype<G>> genotypes = population.stream()
0855                     .filter(pt -> !pt.isEvaluated())
0856                     .map(Phenotype::getGenotype)
0857                     .collect(ISeq.toISeq());
0858 
0859                 if (genotypes.nonEmpty()) {
0860                     final ISeq<C> results = evaluator.evaluate(
0861                         genotypes,
0862                         population.get(0).getFitnessFunction()
0863                     );
0864 
0865                     if (genotypes.size() != results.size()) {
0866                         throw new IllegalStateException(format(
0867                             "Expected %d results, but got %d. " +
0868                             "Check your evaluator function.",
0869                             genotypes.size(), results.size()
0870                         ));
0871                     }
0872 
0873                     final MSeq<Phenotype<G, C>> evaluated = population.asMSeq();
0874                     for (int i = 0, j = 0; i < evaluated.length(); ++i) {
0875                         if (!population.get(i).isEvaluated()) {
0876                             evaluated.set(
0877                                 i,
0878                                 population.get(i).withFitness(results.get(j++))
0879                             );
0880                         }
0881                     }
0882 
0883                     return evaluated.toISeq();
0884                 else {
0885                     return population.asISeq();
0886                 }
0887             };
0888         }
0889 
0890     }
0891 
0892     /**
0893      * This interface gives a different possibility in evaluating the fitness
0894      * values of a population. Sometimes it is necessary (mostly for performance
0895      * reason) to calculate the fitness for the whole population at once. This
0896      * interface allows you to do so. A simple serial evaluator can easily
0897      * implemented:
0898      *
0899      <pre>{@code
0900      * final GenotypeEvaluator<G, C> gte = (g, f) -> g.map(f).asISeq()
0901      * final Evaluator<G, C> evaluator = Evaluator.of(gte);
0902      * }</pre>
0903      *
0904      * @implSpec
0905      * The size of the returned result sequence must be exactly the size of the
0906      * input genotype sequence.
0907      *
0908      * @apiNote
0909      * This interface is an <em>advanced</em> {@code Engine} configuration
0910      * feature, which should be only used when there is a performance gain from
0911      * implementing a different evaluation strategy.
0912      *
0913      @see Evaluator
0914      @see Engine.Builder#evaluator(Engine.GenotypeEvaluator)
0915      *
0916      @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0917      @version 4.2
0918      @since 4.2
0919      */
0920     @FunctionalInterface
0921     public static interface GenotypeEvaluator<
0922         extends Gene<?, G>,
0923         extends Comparable<? super C>
0924     {
0925 
0926         /**
0927          * Calculate the fitness values for the given sequence of genotypes.
0928          *
0929          @see Engine.Evaluator#of(Engine.GenotypeEvaluator)
0930          *
0931          @param genotypes the genotypes to evaluate the fitness value for
0932          @param function the fitness function
0933          @return the fitness values for the given {@code genotypes} The length
0934          *         of the fitness result sequence must match with the size of
0935          *         the given {@code genotypes}.
0936          */
0937         public ISeq<C> evaluate(
0938             final Seq<Genotype<G>> genotypes,
0939             final Function<? super Genotype<G>, ? extends C> function
0940         );
0941 
0942     }
0943 
0944 
0945     /**
0946      * Builder class for building GA {@code Engine} instances.
0947      *
0948      @see Engine
0949      *
0950      @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0951      @since 3.0
0952      @version 4.0
0953      */
0954     public static final class Builder<
0955         extends Gene<?, G>,
0956         extends Comparable<? super C>
0957     >
0958         implements Copyable<Builder<G, C>>
0959     {
0960 
0961         // No default values for this properties.
0962         private Function<? super Genotype<G>, ? extends C> _fitnessFunction;
0963         private Factory<Genotype<G>> _genotypeFactory;
0964 
0965         // This are the properties which default values.
0966         private Function<? super C, ? extends C> _fitnessScaler = a -> a;
0967         private Selector<G, C> _survivorsSelector = new TournamentSelector<>(3);
0968         private Selector<G, C> _offspringSelector = new TournamentSelector<>(3);
0969         private Alterer<G, C> _alterer = Alterer.of(
0970             new SinglePointCrossover<G, C>(0.2),
0971             new Mutator<>(0.15)
0972         );
0973         private Predicate<? super Phenotype<G, C>> _validator = Phenotype::isValid;
0974         private Optimize _optimize = Optimize.MAXIMUM;
0975         private double _offspringFraction = 0.6;
0976         private int _populationSize = 50;
0977         private long _maximalPhenotypeAge = 70;
0978 
0979         // Engine execution environment.
0980         private Executor _executor = ForkJoinPool.commonPool();
0981         private Clock _clock = NanoClock.systemUTC();
0982         private Evaluator<G, C> _evaluator;
0983 
0984         private int _individualCreationRetries = 10;
0985         private UnaryOperator<EvolutionResult<G, C>> _mapper = r -> r;
0986 
0987         private Builder(
0988             final Factory<Genotype<G>> genotypeFactory,
0989             final Function<? super Genotype<G>, ? extends C> fitnessFunction
0990         ) {
0991             _genotypeFactory = requireNonNull(genotypeFactory);
0992             _fitnessFunction = requireNonNull(fitnessFunction);
0993         }
0994 
0995         /**
0996          * Set the fitness function of the evolution {@code Engine}.
0997          *
0998          @param function the fitness function to use in the GA {@code Engine}
0999          @return {@code this} builder, for command chaining
1000          */
1001         public Builder<G, C> fitnessFunction(
1002             final Function<? super Genotype<G>, ? extends C> function
1003         ) {
1004             _fitnessFunction = requireNonNull(function);
1005             return this;
1006         }
1007 
1008         /**
1009          * Set the fitness scaler of the evolution {@code Engine}. <i>Default
1010          * value is set to the identity function.</i>
1011          *
1012          @param scaler the fitness scale to use in the GA {@code Engine}
1013          @return {@code this} builder, for command chaining
1014          *
1015          @deprecated The fitness scaler will be remove in a future version.
1016          */
1017         @Deprecated
1018         public Builder<G, C> fitnessScaler(
1019             final Function<? super C, ? extends C> scaler
1020         ) {
1021             _fitnessScaler = requireNonNull(scaler);
1022             return this;
1023         }
1024 
1025         /**
1026          * The genotype factory used for creating new individuals.
1027          *
1028          @param genotypeFactory the genotype factory for creating new
1029          *        individuals.
1030          @return {@code this} builder, for command chaining
1031          */
1032         public Builder<G, C> genotypeFactory(
1033             final Factory<Genotype<G>> genotypeFactory
1034         ) {
1035             _genotypeFactory = requireNonNull(genotypeFactory);
1036             return this;
1037         }
1038 
1039         /**
1040          * The selector used for selecting the offspring population. <i>Default
1041          * values is set to {@code TournamentSelector<>(3)}.</i>
1042          *
1043          @param selector used for selecting the offspring population
1044          @return {@code this} builder, for command chaining
1045          */
1046         public Builder<G, C> offspringSelector(
1047             final Selector<G, C> selector
1048         ) {
1049             _offspringSelector = requireNonNull(selector);
1050             return this;
1051         }
1052 
1053         /**
1054          * The selector used for selecting the survivors population. <i>Default
1055          * values is set to {@code TournamentSelector<>(3)}.</i>
1056          *
1057          @param selector used for selecting survivors population
1058          @return {@code this} builder, for command chaining
1059          */
1060         public Builder<G, C> survivorsSelector(
1061             final Selector<G, C> selector
1062         ) {
1063             _survivorsSelector = requireNonNull(selector);
1064             return this;
1065         }
1066 
1067         /**
1068          * The selector used for selecting the survivors and offspring
1069          * population. <i>Default values is set to
1070          * {@code TournamentSelector<>(3)}.</i>
1071          *
1072          @param selector used for selecting survivors and offspring population
1073          @return {@code this} builder, for command chaining
1074          */
1075         public Builder<G, C> selector(final Selector<G, C> selector) {
1076             _offspringSelector = requireNonNull(selector);
1077             _survivorsSelector = requireNonNull(selector);
1078             return this;
1079         }
1080 
1081         /**
1082          * The alterers used for alter the offspring population. <i>Default
1083          * values is set to {@code new SinglePointCrossover<>(0.2)} followed by
1084          * {@code new Mutator<>(0.15)}.</i>
1085          *
1086          @param first the first alterer used for alter the offspring
1087          *        population
1088          @param rest the rest of the alterers used for alter the offspring
1089          *        population
1090          @return {@code this} builder, for command chaining
1091          @throws java.lang.NullPointerException if one of the alterers is
1092          *         {@code null}.
1093          */
1094         @SafeVarargs
1095         public final Builder<G, C> alterers(
1096             final Alterer<G, C> first,
1097             final Alterer<G, C>... rest
1098         ) {
1099             requireNonNull(first);
1100             Stream.of(rest).forEach(Objects::requireNonNull);
1101 
1102             _alterer = rest.length == 0
1103                 ? first
1104                 : Alterer.of(rest).compose(first);
1105 
1106             return this;
1107         }
1108 
1109         /**
1110          * The phenotype validator used for detecting invalid individuals.
1111          * Alternatively it is also possible to set the genotype validator with
1112          {@link #genotypeFactory(Factory)}, which will replace any
1113          * previously set phenotype validators.
1114          *
1115          <p><i>Default value is set to {@code Phenotype::isValid}.</i></p>
1116          *
1117          @since 3.1
1118          *
1119          @see #genotypeValidator(Predicate)
1120          *
1121          @param validator the {@code validator} used for validating the
1122          *        individuals (phenotypes).
1123          @return {@code this} builder, for command chaining
1124          @throws java.lang.NullPointerException if the {@code validator} is
1125          *         {@code null}.
1126          */
1127         public Builder<G, C> phenotypeValidator(
1128             final Predicate<? super Phenotype<G, C>> validator
1129         ) {
1130             _validator = requireNonNull(validator);
1131             return this;
1132         }
1133 
1134         /**
1135          * The genotype validator used for detecting invalid individuals.
1136          * Alternatively it is also possible to set the phenotype validator with
1137          {@link #phenotypeValidator(Predicate)}, which will replace any
1138          * previously set genotype validators.
1139          *
1140          <p><i>Default value is set to {@code Genotype::isValid}.</i></p>
1141          *
1142          @since 3.1
1143          *
1144          @see #phenotypeValidator(Predicate)
1145          *
1146          @param validator the {@code validator} used for validating the
1147          *        individuals (genotypes).
1148          @return {@code this} builder, for command chaining
1149          @throws java.lang.NullPointerException if the {@code validator} is
1150          *         {@code null}.
1151          */
1152         public Builder<G, C> genotypeValidator(
1153             final Predicate<? super Genotype<G>> validator
1154         ) {
1155             requireNonNull(validator);
1156 
1157             _validator = pt -> validator.test(pt.getGenotype());
1158             return this;
1159         }
1160 
1161         /**
1162          * The optimization strategy used by the engine. <i>Default values is
1163          * set to {@code Optimize.MAXIMUM}.</i>
1164          *
1165          @param optimize the optimization strategy used by the engine
1166          @return {@code this} builder, for command chaining
1167          */
1168         public Builder<G, C> optimize(final Optimize optimize) {
1169             _optimize = requireNonNull(optimize);
1170             return this;
1171         }
1172 
1173         /**
1174          * Set to a fitness maximizing strategy.
1175          *
1176          @since 3.4
1177          *
1178          @return {@code this} builder, for command chaining
1179          */
1180         public Builder<G, C> maximizing() {
1181             return optimize(Optimize.MAXIMUM);
1182         }
1183 
1184         /**
1185          * Set to a fitness minimizing strategy.
1186          *
1187          @since 3.4
1188          *
1189          @return {@code this} builder, for command chaining
1190          */
1191         public Builder<G, C> minimizing() {
1192             return optimize(Optimize.MINIMUM);
1193         }
1194 
1195         /**
1196          * The offspring fraction. <i>Default values is set to {@code 0.6}.</i>
1197          * This method call is equivalent to
1198          * {@code survivorsFraction(1 - offspringFraction)} and will override
1199          * any previously set survivors-fraction.
1200          *
1201          @see #survivorsFraction(double)
1202          *
1203          @param fraction the offspring fraction
1204          @return {@code this} builder, for command chaining
1205          @throws java.lang.IllegalArgumentException if the fraction is not
1206          *         within the range [0, 1].
1207          */
1208         public Builder<G, C> offspringFraction(final double fraction) {
1209             _offspringFraction = probability(fraction);
1210             return this;
1211         }
1212 
1213         /**
1214          * The survivors fraction. <i>Default values is set to {@code 0.4}.</i>
1215          * This method call is equivalent to
1216          * {@code offspringFraction(1 - survivorsFraction)} and will override
1217          * any previously set offspring-fraction.
1218          *
1219          @since 3.8
1220          *
1221          @see #offspringFraction(double)
1222          *
1223          @param fraction the survivors fraction
1224          @return {@code this} builder, for command chaining
1225          @throws java.lang.IllegalArgumentException if the fraction is not
1226          *         within the range [0, 1].
1227          */
1228         public Builder<G, C> survivorsFraction(final double fraction) {
1229             _offspringFraction = 1.0 - probability(fraction);
1230             return this;
1231         }
1232 
1233         /**
1234          * The number of offspring individuals.
1235          *
1236          @since 3.8
1237          *
1238          @param size the number of offspring individuals.
1239          @return {@code this} builder, for command chaining
1240          @throws java.lang.IllegalArgumentException if the size is not
1241          *         within the range [0, population-size].
1242          */
1243         public Builder<G, C> offspringSize(final int size) {
1244             if (size < 0) {
1245                 throw new IllegalArgumentException(format(
1246                     "Offspring size must be greater or equal zero, but was %s.",
1247                     size
1248                 ));
1249             }
1250 
1251             return offspringFraction((double)size/(double)_populationSize);
1252         }
1253 
1254         /**
1255          * The number of survivors.
1256          *
1257          @since 3.8
1258          *
1259          @param size the number of survivors.
1260          @return {@code this} builder, for command chaining
1261          @throws java.lang.IllegalArgumentException if the size is not
1262          *         within the range [0, population-size].
1263          */
1264         public Builder<G, C> survivorsSize(final int size) {
1265             if (size < 0) {
1266                 throw new IllegalArgumentException(format(
1267                     "Survivors must be greater or equal zero, but was %s.",
1268                     size
1269                 ));
1270             }
1271 
1272             return survivorsFraction((double)size/(double)_populationSize);
1273         }
1274 
1275         /**
1276          * The number of individuals which form the population. <i>Default
1277          * values is set to {@code 50}.</i>
1278          *
1279          @param size the number of individuals of a population
1280          @return {@code this} builder, for command chaining
1281          @throws java.lang.IllegalArgumentException if {@code size < 1}
1282          */
1283         public Builder<G, C> populationSize(final int size) {
1284             if (size < 1) {
1285                 throw new IllegalArgumentException(format(
1286                     "Population size must be greater than zero, but was %s.",
1287                     size
1288                 ));
1289             }
1290             _populationSize = size;
1291             return this;
1292         }
1293 
1294         /**
1295          * The maximal allowed age of a phenotype. <i>Default values is set to
1296          * {@code 70}.</i>
1297          *
1298          @param age the maximal phenotype age
1299          @return {@code this} builder, for command chaining
1300          @throws java.lang.IllegalArgumentException if {@code age < 1}
1301          */
1302         public Builder<G, C> maximalPhenotypeAge(final long age) {
1303             if (age < 1) {
1304                 throw new IllegalArgumentException(format(
1305                     "Phenotype age must be greater than one, but was %s.", age
1306                 ));
1307             }
1308             _maximalPhenotypeAge = age;
1309             return this;
1310         }
1311 
1312         /**
1313          * The executor used by the engine.
1314          *
1315          @param executor the executor used by the engine
1316          @return {@code this} builder, for command chaining
1317          */
1318         public Builder<G, C> executor(final Executor executor) {
1319             _executor = requireNonNull(executor);
1320             return this;
1321         }
1322 
1323         /**
1324          * The clock used for calculating the execution durations.
1325          *
1326          @param clock the clock used for calculating the execution durations
1327          @return {@code this} builder, for command chaining
1328          */
1329         public Builder<G, C> clock(final Clock clock) {
1330             _clock = requireNonNull(clock);
1331             return this;
1332         }
1333 
1334         /**
1335          * The phenotype evaluator allows to change the evaluation strategy.
1336          * By default, the population is evaluated concurrently using the
1337          * defined {@link Executor} implementation.
1338          *
1339          * @apiNote
1340          * This is an <em>advanced</em> {@code Engine} configuration feature,
1341          * which should be only used when there is a performance gain from
1342          * implementing a different evaluation strategy.
1343          *
1344          @since 4.2
1345          *
1346          @param evaluator the population evaluation strategy
1347          @return {@code this} builder, for command chaining
1348          */
1349         public Builder<G, C> evaluator(final Evaluator<G, C> evaluator) {
1350             _evaluator = requireNonNull(evaluator);
1351             return this;
1352         }
1353 
1354         /**
1355          * Setting the <em>genotype</em> evaluator used for evaluating the
1356          * fitness function of the population.
1357          *
1358          * @apiNote
1359          * This is an <em>advanced</em> {@code Engine} configuration feature,
1360          * which should be only used when there is a performance gain from
1361          * implementing a different evaluation strategy.
1362          *
1363          @since 4.2
1364          *
1365          @param evaluator the genotype evaluator
1366          @return {@code this} builder, for command chaining
1367          */
1368         public Builder<G, C> evaluator(final GenotypeEvaluator<G, C> evaluator) {
1369             _evaluator = Evaluator.of(evaluator);
1370             return this;
1371         }
1372 
1373         /**
1374          * The maximal number of attempt before the {@code Engine} gives up
1375          * creating a valid individual ({@code Phenotype}). <i>Default values is
1376          * set to {@code 10}.</i>
1377          *
1378          @since 3.1
1379          *
1380          @param retries the maximal retry count
1381          @throws IllegalArgumentException if the given retry {@code count} is
1382          *         smaller than zero.
1383          @return {@code this} builder, for command chaining
1384          */
1385         public Builder<G, C> individualCreationRetries(final int retries) {
1386             if (retries < 0) {
1387                 throw new IllegalArgumentException(format(
1388                     "Retry count must not be negative: %d",
1389                     retries
1390                 ));
1391             }
1392             _individualCreationRetries = retries;
1393             return this;
1394         }
1395 
1396         /**
1397          * The result mapper, which allows to change the evolution result after
1398          * each generation.
1399          *
1400          @since 4.0
1401          @see EvolutionResult#toUniquePopulation()
1402          *
1403          @param mapper the evolution result mapper
1404          @return {@code this} builder, for command chaining
1405          @throws NullPointerException if the given {@code resultMapper} is
1406          *         {@code null}
1407          */
1408         public Builder<G, C> mapping(
1409             final Function<
1410                 super EvolutionResult<G, C>,
1411                 EvolutionResult<G, C>
1412             > mapper
1413         ) {
1414             _mapper = requireNonNull(mapper::apply);
1415             return this;
1416         }
1417 
1418         /**
1419          * Builds an new {@code Engine} instance from the set properties.
1420          *
1421          @return an new {@code Engine} instance from the set properties
1422          */
1423         public Engine<G, C> build() {
1424             return new Engine<>(
1425                 _fitnessFunction,
1426                 _genotypeFactory,
1427                 _fitnessScaler,
1428                 _survivorsSelector,
1429                 _offspringSelector,
1430                 _alterer,
1431                 _validator,
1432                 _optimize,
1433                 getOffspringCount(),
1434                 getSurvivorsCount(),
1435                 _maximalPhenotypeAge,
1436                 _executor,
1437                 _evaluator != null
1438                     ? _evaluator
1439                     new ConcurrentEvaluator<>(_executor),
1440                 _clock,
1441                 _individualCreationRetries,
1442                 _mapper
1443             );
1444         }
1445 
1446         private int getSurvivorsCount() {
1447             return _populationSize - getOffspringCount();
1448         }
1449 
1450         private int getOffspringCount() {
1451             return (int)round(_offspringFraction*_populationSize);
1452         }
1453 
1454         /**
1455          * Return the used {@link Alterer} of the GA.
1456          *
1457          @return the used {@link Alterer} of the GA.
1458          */
1459         public Alterer<G, C> getAlterers() {
1460             return _alterer;
1461         }
1462 
1463         /**
1464          * Return the {@link Clock} the engine is using for measuring the execution
1465          * time.
1466          *
1467          @since 3.1
1468          *
1469          @return the clock used for measuring the execution time
1470          */
1471         public Clock getClock() {
1472             return _clock;
1473         }
1474 
1475         /**
1476          * Return the {@link Executor} the engine is using for executing the
1477          * evolution steps.
1478          *
1479          @since 3.1
1480          *
1481          @return the executor used for performing the evolution steps
1482          */
1483         public Executor getExecutor() {
1484             return _executor;
1485         }
1486 
1487         /**
1488          * Return the fitness function of the GA engine.
1489          *
1490          @since 3.1
1491          *
1492          @return the fitness function
1493          */
1494         public Function<? super Genotype<G>, ? extends C> getFitnessFunction() {
1495             return _fitnessFunction;
1496         }
1497 
1498         /**
1499          * Return the fitness scaler of the GA engine.
1500          *
1501          @since 3.1
1502          *
1503          @return the fitness scaler
1504          *
1505          @deprecated The fitness scaler will be remove in a future version.
1506          */
1507         @Deprecated
1508         public Function<? super C, ? extends C> getFitnessScaler() {
1509             return _fitnessScaler;
1510         }
1511 
1512         /**
1513          * Return the used genotype {@link Factory} of the GA. The genotype factory
1514          * is used for creating the initial population and new, random individuals
1515          * when needed (as replacement for invalid and/or died genotypes).
1516          *
1517          @since 3.1
1518          *
1519          @return the used genotype {@link Factory} of the GA.
1520          */
1521         public Factory<Genotype<G>> getGenotypeFactory() {
1522             return _genotypeFactory;
1523         }
1524 
1525         /**
1526          * Return the maximal allowed phenotype age.
1527          *
1528          @since 3.1
1529          *
1530          @return the maximal allowed phenotype age
1531          */
1532         public long getMaximalPhenotypeAge() {
1533             return _maximalPhenotypeAge;
1534         }
1535 
1536         /**
1537          * Return the offspring fraction.
1538          *
1539          @return the offspring fraction.
1540          */
1541         public double getOffspringFraction() {
1542             return _offspringFraction;
1543         }
1544 
1545         /**
1546          * Return the used offspring {@link Selector} of the GA.
1547          *
1548          @since 3.1
1549          *
1550          @return the used offspring {@link Selector} of the GA.
1551          */
1552         public Selector<G, C> getOffspringSelector() {
1553             return _offspringSelector;
1554         }
1555 
1556         /**
1557          * Return the used survivor {@link Selector} of the GA.
1558          *
1559          @since 3.1
1560          *
1561          @return the used survivor {@link Selector} of the GA.
1562          */
1563         public Selector<G, C> getSurvivorsSelector() {
1564             return _survivorsSelector;
1565         }
1566 
1567         /**
1568          * Return the optimization strategy.
1569          *
1570          @since 3.1
1571          *
1572          @return the optimization strategy
1573          */
1574         public Optimize getOptimize() {
1575             return _optimize;
1576         }
1577 
1578         /**
1579          * Return the number of individuals of a population.
1580          *
1581          @since 3.1
1582          *
1583          @return the number of individuals of a population
1584          */
1585         public int getPopulationSize() {
1586             return _populationSize;
1587         }
1588 
1589         /**
1590          * Return the maximal number of attempt before the {@code Engine} gives
1591          * up creating a valid individual ({@code Phenotype}).
1592          *
1593          @since 3.1
1594          *
1595          @return the maximal number of {@code Phenotype} creation attempts
1596          */
1597         public int getIndividualCreationRetries() {
1598             return _individualCreationRetries;
1599         }
1600 
1601         /**
1602          * Return the evolution result mapper.
1603          *
1604          @since 4.0
1605          *
1606          @return the evolution result mapper
1607          */
1608         public UnaryOperator<EvolutionResult<G, C>> getMapper() {
1609             return _mapper;
1610         }
1611 
1612         /**
1613          * Create a new builder, with the current configuration.
1614          *
1615          @since 3.1
1616          *
1617          @return a new builder, with the current configuration
1618          */
1619         @Override
1620         public Builder<G, C> copy() {
1621             return new Builder<G, C>(_genotypeFactory, _fitnessFunction)
1622                 .alterers(_alterer)
1623                 .clock(_clock)
1624                 .executor(_executor)
1625                 .evaluator(_evaluator)
1626                 .fitnessScaler(_fitnessScaler)
1627                 .maximalPhenotypeAge(_maximalPhenotypeAge)
1628                 .offspringFraction(_offspringFraction)
1629                 .offspringSelector(_offspringSelector)
1630                 .phenotypeValidator(_validator)
1631                 .optimize(_optimize)
1632                 .populationSize(_populationSize)
1633                 .survivorsSelector(_survivorsSelector)
1634                 .individualCreationRetries(_individualCreationRetries)
1635                 .mapping(_mapper);
1636         }
1637 
1638     }
1639 
1640 }