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