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