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