001/*
002 * Java Genetic Algorithm Library (jenetics-4.0.0).
003 * Copyright (c) 2007-2017 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020package io.jenetics.engine;
021
022import static java.lang.Math.round;
023import static java.lang.String.format;
024import static java.util.Objects.requireNonNull;
025import static io.jenetics.internal.util.require.probability;
026
027import java.time.Clock;
028import java.util.Iterator;
029import java.util.Objects;
030import java.util.concurrent.CompletableFuture;
031import java.util.concurrent.Executor;
032import java.util.concurrent.ForkJoinPool;
033import java.util.function.Function;
034import java.util.function.Predicate;
035import java.util.function.UnaryOperator;
036import java.util.stream.Stream;
037import java.util.stream.StreamSupport;
038
039import io.jenetics.Alterer;
040import io.jenetics.AltererResult;
041import io.jenetics.Chromosome;
042import io.jenetics.Gene;
043import io.jenetics.Genotype;
044import io.jenetics.Mutator;
045import io.jenetics.Optimize;
046import io.jenetics.Phenotype;
047import io.jenetics.Selector;
048import io.jenetics.SinglePointCrossover;
049import io.jenetics.TournamentSelector;
050import io.jenetics.internal.util.Concurrency;
051import io.jenetics.internal.util.require;
052import io.jenetics.util.Copyable;
053import io.jenetics.util.Factory;
054import io.jenetics.util.ISeq;
055import io.jenetics.util.MSeq;
056import io.jenetics.util.NanoClock;
057import io.jenetics.util.Seq;
058
059/**
060 * Genetic algorithm <em>engine</em> which is the main class. The following
061 * example shows the main steps in initializing and executing the GA.
062 *
063 * <pre>{@code
064 * public class RealFunction {
065 *    // Definition of the fitness function.
066 *    private static Double eval(final Genotype<DoubleGene> gt) {
067 *        final double x = gt.getGene().doubleValue();
068 *        return cos(0.5 + sin(x))*cos(x);
069 *    }
070 *
071 *    public static void main(String[] args) {
072 *        // Create/configuring the engine via its builder.
073 *        final Engine<DoubleGene, Double> engine = Engine
074 *            .builder(
075 *                RealFunction::eval,
076 *                DoubleChromosome.of(0.0, 2.0*PI))
077 *            .populationSize(500)
078 *            .optimize(Optimize.MINIMUM)
079 *            .alterers(
080 *                new Mutator<>(0.03),
081 *                new MeanAlterer<>(0.6))
082 *            .build();
083 *
084 *        // Execute the GA (engine).
085 *        final Phenotype<DoubleGene, Double> result = engine.stream()
086 *             // Truncate the evolution stream if no better individual could
087 *             // be found after 5 consecutive generations.
088 *            .limit(bySteadyFitness(5))
089 *             // Terminate the evolution after maximal 100 generations.
090 *            .limit(100)
091 *            .collect(toBestPhenotype());
092 *     }
093 * }
094 * }</pre>
095 *
096 * The architecture allows to decouple the configuration of the engine from the
097 * execution. The {@code Engine} is configured via the {@code Engine.Builder}
098 * class and can't be changed after creation. The actual <i>evolution</i> is
099 * performed by the {@link EvolutionStream}, which is created by the
100 * {@code Engine}.
101 * <p>
102 * <em>
103 *     <b>This class is thread safe:</b>
104 *     No mutable state is maintained by the engine. Therefore it is save to
105 *     create multiple evolution streams with one engine, which may be actually
106 *     used in different threads.
107 * </em>
108 *
109 * @see Engine.Builder
110 * @see EvolutionStart
111 * @see EvolutionResult
112 * @see EvolutionStream
113 * @see EvolutionStatistics
114 * @see Codec
115 *
116 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
117 * @since 3.0
118 * @version 4.0
119 */
120public final class Engine<
121        G extends Gene<?, G>,
122        C extends Comparable<? super C>
123>
124        implements Function<EvolutionStart<G, C>, EvolutionResult<G, C>>
125{
126
127        // Problem definition.
128        private final Function<? super Genotype<G>, ? extends C> _fitnessFunction;
129        private final Factory<Genotype<G>> _genotypeFactory;
130
131        // Evolution parameters.
132        private final Function<? super C, ? extends C> _fitnessScaler;
133        private final Selector<G, C> _survivorsSelector;
134        private final Selector<G, C> _offspringSelector;
135        private final Alterer<G, C> _alterer;
136        private final Predicate<? super Phenotype<G, C>> _validator;
137        private final Optimize _optimize;
138        private final int _offspringCount;
139        private final int _survivorsCount;
140        private final long _maximalPhenotypeAge;
141
142        // Execution context for concurrent execution of evolving steps.
143        private final TimedExecutor _executor;
144        private final Clock _clock;
145
146        // Additional parameters.
147        private final int _individualCreationRetries;
148        private final UnaryOperator<EvolutionResult<G, C>> _mapper;
149
150
151        /**
152         * Create a new GA engine with the given parameters.
153         *
154         * @param fitnessFunction the fitness function this GA is using.
155         * @param genotypeFactory the genotype factory this GA is working with.
156         * @param fitnessScaler the fitness scaler this GA is using.
157         * @param survivorsSelector the selector used for selecting the survivors
158         * @param offspringSelector the selector used for selecting the offspring
159         * @param alterer the alterer used for altering the offspring
160         * @param validator phenotype validator which can override the default
161         *        implementation the {@link Phenotype#isValid()} method.
162         * @param optimize the kind of optimization (minimize or maximize)
163         * @param offspringCount the number of the offspring individuals
164         * @param survivorsCount the number of the survivor individuals
165         * @param maximalPhenotypeAge the maximal age of an individual
166         * @param executor the executor used for executing the single evolve steps
167         * @param clock the clock used for calculating the timing results
168         * @param individualCreationRetries the maximal number of attempts for
169         *        creating a valid individual.
170         * @throws NullPointerException if one of the arguments is {@code null}
171         * @throws IllegalArgumentException if the given integer values are smaller
172         *         than one.
173         */
174        Engine(
175                final Function<? super Genotype<G>, ? extends C> fitnessFunction,
176                final Factory<Genotype<G>> genotypeFactory,
177                final Function<? super C, ? extends C> fitnessScaler,
178                final Selector<G, C> survivorsSelector,
179                final Selector<G, C> offspringSelector,
180                final Alterer<G, C> alterer,
181                final Predicate<? super Phenotype<G, C>> validator,
182                final Optimize optimize,
183                final int offspringCount,
184                final int survivorsCount,
185                final long maximalPhenotypeAge,
186                final Executor executor,
187                final Clock clock,
188                final int individualCreationRetries,
189                final UnaryOperator<EvolutionResult<G, C>> mapper
190        ) {
191                _fitnessFunction = requireNonNull(fitnessFunction);
192                _fitnessScaler = requireNonNull(fitnessScaler);
193                _genotypeFactory = requireNonNull(genotypeFactory);
194                _survivorsSelector = requireNonNull(survivorsSelector);
195                _offspringSelector = requireNonNull(offspringSelector);
196                _alterer = requireNonNull(alterer);
197                _validator = requireNonNull(validator);
198                _optimize = requireNonNull(optimize);
199
200                _offspringCount = require.nonNegative(offspringCount);
201                _survivorsCount = require.nonNegative(survivorsCount);
202                _maximalPhenotypeAge = require.positive(maximalPhenotypeAge);
203
204                _executor = new TimedExecutor(requireNonNull(executor));
205                _clock = requireNonNull(clock);
206
207                if (individualCreationRetries < 0) {
208                        throw new IllegalArgumentException(format(
209                                "Retry count must not be negative: %d",
210                                individualCreationRetries
211                        ));
212                }
213                _individualCreationRetries = individualCreationRetries;
214                _mapper = requireNonNull(mapper);
215        }
216
217        /**
218         * Perform one evolution step with the given {@code population} and
219         * {@code generation}. New phenotypes are created with the fitness function
220         * and fitness scaler defined by this <em>engine</em>
221         * <p>
222         * <em>This method is thread-safe.</em>
223         *
224         * @see #evolve(EvolutionStart)
225         *
226         * @param population the population to evolve
227         * @param generation the current generation; used for calculating the
228         *        phenotype age.
229         * @return the evolution result
230         * @throws java.lang.NullPointerException if the given {@code population} is
231         *         {@code null}
232         * @throws IllegalArgumentException if the given {@code generation} is
233         *         smaller then one
234         */
235        public EvolutionResult<G, C> evolve(
236                final ISeq<Phenotype<G, C>> population,
237                final long generation
238        ) {
239                return evolve(EvolutionStart.of(population, generation));
240        }
241
242        /**
243         * Perform one evolution step with the given evolution {@code start} object
244         * New phenotypes are created with the fitness function and fitness scaler
245         * defined by this <em>engine</em>
246         * <p>
247         * <em>This method is thread-safe.</em>
248         *
249         * @since 3.1
250         * @see #evolve(ISeq, long)
251         *
252         * @param start the evolution start object
253         * @return the evolution result
254         * @throws java.lang.NullPointerException if the given evolution
255         *         {@code start} is {@code null}
256         */
257        public EvolutionResult<G, C> evolve(final EvolutionStart<G, C> start) {
258                final Timer timer = Timer.of(_clock).start();
259
260                // Initial evaluation of the population.
261                final Timer evaluateTimer = Timer.of(_clock).start();
262                evaluate(start.getPopulation());
263                evaluateTimer.stop();
264
265                // Select the offspring population.
266                final CompletableFuture<TimedResult<ISeq<Phenotype<G, C>>>> offspring =
267                        _executor.async(() ->
268                                selectOffspring(start.getPopulation()),
269                                _clock
270                        );
271
272                // Select the survivor population.
273                final CompletableFuture<TimedResult<ISeq<Phenotype<G, C>>>> survivors =
274                        _executor.async(() ->
275                                selectSurvivors(start.getPopulation()),
276                                _clock
277                        );
278
279                // Altering the offspring population.
280                final CompletableFuture<TimedResult<AltererResult<G, C>>> alteredOffspring =
281                        _executor.thenApply(offspring, p ->
282                                _alterer.alter(p.result, start.getGeneration()),
283                                _clock
284                        );
285
286                // Filter and replace invalid and old survivor individuals.
287                final CompletableFuture<TimedResult<FilterResult<G, C>>> filteredSurvivors =
288                        _executor.thenApply(survivors, pop ->
289                                filter(pop.result, start.getGeneration()),
290                                _clock
291                        );
292
293                // Filter and replace invalid and old offspring individuals.
294                final CompletableFuture<TimedResult<FilterResult<G, C>>> filteredOffspring =
295                        _executor.thenApply(alteredOffspring, pop ->
296                                filter(pop.result.getPopulation(), start.getGeneration()),
297                                _clock
298                        );
299
300                // Combining survivors and offspring to the new population.
301                final CompletableFuture<ISeq<Phenotype<G, C>>> population =
302                        filteredSurvivors.thenCombineAsync(filteredOffspring, (s, o) ->
303                                        ISeq.of(s.result.population.append(o.result.population)),
304                                _executor.get()
305                        );
306
307                // Evaluate the fitness-function and wait for result.
308                final ISeq<Phenotype<G, C>> pop = population.join();
309                final TimedResult<ISeq<Phenotype<G, C>>> result = TimedResult
310                        .of(() -> evaluate(pop), _clock)
311                        .get();
312
313
314                final EvolutionDurations durations = EvolutionDurations.of(
315                        offspring.join().duration,
316                        survivors.join().duration,
317                        alteredOffspring.join().duration,
318                        filteredOffspring.join().duration,
319                        filteredSurvivors.join().duration,
320                        result.duration.plus(evaluateTimer.getTime()),
321                        timer.stop().getTime()
322                );
323
324                final int killCount =
325                        filteredOffspring.join().result.killCount +
326                        filteredSurvivors.join().result.killCount;
327
328                final int invalidCount =
329                        filteredOffspring.join().result.invalidCount +
330                        filteredSurvivors.join().result.invalidCount;
331
332                return _mapper.apply(
333                        EvolutionResult.of(
334                                _optimize,
335                                result.result,
336                                start.getGeneration(),
337                                durations,
338                                killCount,
339                                invalidCount,
340                                alteredOffspring.join().result.getAlterations()
341                        )
342                );
343        }
344
345        /**
346         * This method is an <i>alias</i> for the {@link #evolve(EvolutionStart)}
347         * method.
348         *
349         * @since 3.1
350         */
351        @Override
352        public EvolutionResult<G, C> apply(final EvolutionStart<G, C> start) {
353                return evolve(start);
354        }
355
356        // Selects the survivors population. A new population object is returned.
357        private ISeq<Phenotype<G, C>> selectSurvivors(final ISeq<Phenotype<G, C>> population) {
358                return _survivorsCount > 0
359                        ?_survivorsSelector.select(population, _survivorsCount, _optimize)
360                        : ISeq.empty();
361        }
362
363        // Selects the offspring population. A new population object is returned.
364        private ISeq<Phenotype<G, C>> selectOffspring(final ISeq<Phenotype<G, C>> population) {
365                return _offspringCount > 0
366                        ? _offspringSelector.select(population, _offspringCount, _optimize)
367                        : ISeq.empty();
368        }
369
370        // Filters out invalid and old individuals. Filtering is done in place.
371        private FilterResult<G, C> filter(
372                final Seq<Phenotype<G, C>> population,
373                final long generation
374        ) {
375                int killCount = 0;
376                int invalidCount = 0;
377
378                final MSeq<Phenotype<G, C>> pop = MSeq.of(population);
379                for (int i = 0, n = pop.size(); i < n; ++i) {
380                        final Phenotype<G, C> individual = pop.get(i);
381
382                        if (!_validator.test(individual)) {
383                                pop.set(i, newPhenotype(generation));
384                                ++invalidCount;
385                        } else if (individual.getAge(generation) > _maximalPhenotypeAge) {
386                                pop.set(i, newPhenotype(generation));
387                                ++killCount;
388                        }
389                }
390
391                return new FilterResult<>(pop.toISeq(), killCount, invalidCount);
392        }
393
394        // Create a new and valid phenotype
395        private Phenotype<G, C> newPhenotype(final long generation) {
396                int count = 0;
397                Phenotype<G, C> phenotype;
398                do {
399                        phenotype = Phenotype.of(
400                                _genotypeFactory.newInstance(),
401                                generation,
402                                _fitnessFunction,
403                                _fitnessScaler
404                        );
405                } while (++count < _individualCreationRetries &&
406                                !_validator.test(phenotype));
407
408                return phenotype;
409        }
410
411        // Evaluates the fitness function of the give population concurrently.
412        private ISeq<Phenotype<G, C>> evaluate(final ISeq<Phenotype<G, C>> population) {
413                try (Concurrency c = Concurrency.with(_executor.get())) {
414                        c.execute(population);
415                }
416                return population;
417        }
418
419
420        /* *************************************************************************
421         * Evolution Stream/Iterator creation.
422         **************************************************************************/
423
424        /**
425         * Create a new <b>infinite</b> evolution iterator with a newly created
426         * population. This is an alternative way for evolution. It lets the user
427         * start, stop and resume the evolution process whenever desired.
428         *
429         * @return a new <b>infinite</b> evolution iterator
430         */
431        public Iterator<EvolutionResult<G, C>> iterator() {
432                return new EvolutionIterator<>(
433                        this::evolutionStart,
434                        this::evolve
435                );
436        }
437
438        /**
439         * Create a new <b>infinite</b> evolution stream with a newly created
440         * population.
441         *
442         * @return a new evolution stream.
443         */
444        public EvolutionStream<G, C> stream() {
445                return EvolutionStream.of(this::evolutionStart, this::evolve);
446        }
447
448        private EvolutionStart<G, C> evolutionStart() {
449                final int generation = 1;
450                final int size = _offspringCount + _survivorsCount;
451
452                final ISeq<Phenotype<G, C>> population = MSeq.<Phenotype<G, C>>ofLength(size)
453                        .fill(() -> newPhenotype(generation))
454                        .toISeq();
455
456                return EvolutionStart.of(population, generation);
457        }
458
459        /**
460         * Create a new <b>infinite</b> evolution iterator with the given initial
461         * individuals. If an empty {@code Iterable} is given, the engines genotype
462         * factory is used for creating the population.
463         *
464         * @param genotypes the initial individuals used for the evolution iterator.
465         *        Missing individuals are created and individuals not needed are
466         *        skipped.
467         * @return a new <b>infinite</b> evolution iterator
468         * @throws java.lang.NullPointerException if the given {@code genotypes} is
469         *         {@code null}.
470         */
471        public Iterator<EvolutionResult<G, C>> iterator(
472                final Iterable<Genotype<G>> genotypes
473        ) {
474                requireNonNull(genotypes);
475
476                return new EvolutionIterator<>(
477                        () -> evolutionStart(genotypes, 1),
478                        this::evolve
479                );
480        }
481
482        /**
483         * Create a new <b>infinite</b> evolution stream with the given initial
484         * individuals. If an empty {@code Iterable} is given, the engines genotype
485         * factory is used for creating the population.
486         *
487         * @since 3.7
488         *
489         * @param genotypes the initial individuals used for the evolution stream.
490         *        Missing individuals are created and individuals not needed are
491         *        skipped.
492         * @return a new evolution stream.
493         * @throws java.lang.NullPointerException if the given {@code genotypes} is
494         *         {@code null}.
495         */
496        public EvolutionStream<G, C> stream(final Iterable<Genotype<G>> genotypes) {
497                requireNonNull(genotypes);
498
499                return EvolutionStream.of(
500                        () -> evolutionStart(genotypes, 1),
501                        this::evolve
502                );
503        }
504
505        private EvolutionStart<G, C> evolutionStart(
506                final Iterable<Genotype<G>> genotypes,
507                final long generation
508        ) {
509                final Stream<Phenotype<G, C>> stream = Stream.concat(
510                        StreamSupport.stream(genotypes.spliterator(), false)
511                                .map(gt -> Phenotype.of(
512                                        gt, generation, _fitnessFunction, _fitnessScaler)),
513                        Stream.generate(() -> newPhenotype(generation))
514                );
515
516                final ISeq<Phenotype<G, C>> population = stream
517                        .limit(getPopulationSize())
518                        .collect(ISeq.toISeq());
519
520                return EvolutionStart.of(population, generation);
521        }
522
523        /**
524         * Create a new <b>infinite</b> evolution iterator with the given initial
525         * individuals. If an empty {@code Iterable} is given, the engines genotype
526         * factory is used for creating the population.
527         *
528         * @since 3.7
529         *
530         * @param genotypes the initial individuals used for the evolution iterator.
531         *        Missing individuals are created and individuals not needed are
532         *        skipped.
533         * @param generation the generation the stream starts from; must be greater
534         *        than zero.
535         * @return a new <b>infinite</b> evolution iterator
536         * @throws java.lang.NullPointerException if the given {@code genotypes} is
537         *         {@code null}.
538         * @throws IllegalArgumentException if the given {@code generation} is
539         *         smaller then one
540         */
541        public Iterator<EvolutionResult<G, C>> iterator(
542                final Iterable<Genotype<G>> genotypes,
543                final long generation
544        ) {
545                requireNonNull(genotypes);
546                require.positive(generation);
547
548                return new EvolutionIterator<>(
549                        () -> evolutionStart(genotypes, generation),
550                        this::evolve
551                );
552        }
553
554        /**
555         * Create a new <b>infinite</b> evolution stream with the given initial
556         * individuals. If an empty {@code Iterable} is given, the engines genotype
557         * factory is used for creating the population.
558         *
559         * @since 3.7
560         *
561         * @param genotypes the initial individuals used for the evolution stream.
562         *        Missing individuals are created and individuals not needed are
563         *        skipped.
564         * @param generation the generation the stream starts from; must be greater
565         *        than zero.
566         * @return a new evolution stream.
567         * @throws java.lang.NullPointerException if the given {@code genotypes} is
568         *         {@code null}.
569         * @throws IllegalArgumentException if the given {@code generation} is
570         *         smaller then one
571         */
572        public EvolutionStream<G, C> stream(
573                final Iterable<Genotype<G>> genotypes,
574                final long generation
575        ) {
576                requireNonNull(genotypes);
577
578                return EvolutionStream.of(
579                        () -> evolutionStart(genotypes, generation),
580                        this::evolve
581                );
582        }
583
584        /**
585         * Create a new <b>infinite</b> evolution iterator with the given initial
586         * population. If an empty {@code Population} is given, the engines genotype
587         * factory is used for creating the population. The given population might
588         * be the result of an other engine and this method allows to start the
589         * evolution with the outcome of an different engine. The fitness function
590         * and the fitness scaler are replaced by the one defined for this engine.
591         *
592         * @since 3.7
593         *
594         * @param population the initial individuals used for the evolution iterator.
595         *        Missing individuals are created and individuals not needed are
596         *        skipped.
597         * @return a new <b>infinite</b> evolution iterator
598         * @throws java.lang.NullPointerException if the given {@code population} is
599         *         {@code null}.
600         */
601        public Iterator<EvolutionResult<G, C>> iterator(
602                final ISeq<Phenotype<G, C>> population
603        ) {
604                requireNonNull(population);
605
606                return new EvolutionIterator<>(
607                        () -> evolutionStart(population, 1),
608                        this::evolve
609                );
610        }
611
612        /**
613         * Create a new <b>infinite</b> evolution stream with the given initial
614         * population. If an empty {@code Population} is given, the engines genotype
615         * factory is used for creating the population. The given population might
616         * be the result of an other engine and this method allows to start the
617         * evolution with the outcome of an different engine. The fitness function
618         * and the fitness scaler are replaced by the one defined for this engine.
619         *
620         * @param population the initial individuals used for the evolution stream.
621         *        Missing individuals are created and individuals not needed are
622         *        skipped.
623         * @return a new evolution stream.
624         * @throws java.lang.NullPointerException if the given {@code population} is
625         *         {@code null}.
626         */
627        public EvolutionStream<G, C> stream(
628                final ISeq<Phenotype<G, C>> population
629        ) {
630                requireNonNull(population);
631
632                return EvolutionStream.of(
633                        () -> evolutionStart(population, 1),
634                        this::evolve
635                );
636        }
637
638        private EvolutionStart<G, C> evolutionStart(
639                final Seq<Phenotype<G, C>> population,
640                final long generation
641        ) {
642                final Stream<Phenotype<G, C>> stream = Stream.concat(
643                        population.stream()
644                                .map(p -> p.newInstance(
645                                        p.getGeneration(),
646                                        _fitnessFunction,
647                                        _fitnessScaler)),
648                        Stream.generate(() -> newPhenotype(generation))
649                );
650
651                final ISeq<Phenotype<G, C>> pop = stream
652                        .limit(getPopulationSize())
653                        .collect(ISeq.toISeq());
654
655                return EvolutionStart.of(pop, generation);
656        }
657
658        /**
659         * Create a new <b>infinite</b> evolution iterator with the given initial
660         * population. If an empty {@code Population} is given, the engines genotype
661         * factory is used for creating the population. The given population might
662         * be the result of an other engine and this method allows to start the
663         * evolution with the outcome of an different engine. The fitness function
664         * and the fitness scaler are replaced by the one defined for this engine.
665         *
666         * @param population the initial individuals used for the evolution iterator.
667         *        Missing individuals are created and individuals not needed are
668         *        skipped.
669         * @param generation the generation the iterator starts from; must be greater
670         *        than zero.
671         * @return a new <b>infinite</b> evolution iterator
672         * @throws java.lang.NullPointerException if the given {@code population} is
673         *         {@code null}.
674         * @throws IllegalArgumentException if the given {@code generation} is smaller
675         *        then one
676         */
677        public Iterator<EvolutionResult<G, C>> iterator(
678                final ISeq<Phenotype<G, C>> population,
679                final long generation
680        ) {
681                requireNonNull(population);
682                require.positive(generation);
683
684                return new EvolutionIterator<>(
685                        () -> evolutionStart(population, generation),
686                        this::evolve
687                );
688        }
689
690        /**
691         * Create a new <b>infinite</b> evolution stream with the given initial
692         * population. If an empty {@code Population} is given, the engines genotype
693         * factory is used for creating the population. The given population might
694         * be the result of an other engine and this method allows to start the
695         * evolution with the outcome of an different engine. The fitness function
696         * and the fitness scaler are replaced by the one defined for this engine.
697         *
698         * @param population the initial individuals used for the evolution stream.
699         *        Missing individuals are created and individuals not needed are
700         *        skipped.
701         * @param generation the generation the stream starts from; must be greater
702         *        than zero.
703         * @return a new evolution stream.
704         * @throws java.lang.NullPointerException if the given {@code population} is
705         *         {@code null}.
706         * @throws IllegalArgumentException if the given {@code generation} is
707         *         smaller then one
708         */
709        public EvolutionStream<G, C> stream(
710                final ISeq<Phenotype<G, C>> population,
711                final long generation
712        ) {
713                requireNonNull(population);
714                require.positive(generation);
715
716                return EvolutionStream.of(
717                        () -> evolutionStart(population, generation),
718                        this::evolve
719                );
720        }
721
722        /**
723         * Create a new <b>infinite</b> evolution iterator starting with a
724         * previously evolved {@link EvolutionResult}. The iterator is initialized
725         * with the population of the given {@code result} and its total generation
726         * {@link EvolutionResult#getTotalGenerations()}.
727         *
728         * @since 3.7
729         *
730         * @param result the previously evolved {@code EvolutionResult}
731         * @return a new evolution stream, which continues a previous one
732         * @throws NullPointerException if the given evolution {@code result} is
733         *         {@code null}
734         */
735        public Iterator<EvolutionResult<G, C>> iterator(
736                final EvolutionResult<G, C> result
737        ) {
738                return iterator(result.getPopulation(), result.getTotalGenerations());
739        }
740
741        /**
742         * Create a new {@code EvolutionStream} starting with a previously evolved
743         * {@link EvolutionResult}. The stream is initialized with the population
744         * of the given {@code result} and its total generation
745         * {@link EvolutionResult#getTotalGenerations()}.
746         *
747         * <pre>{@code
748         * private static final Problem<Double, DoubleGene, Double>
749         * PROBLEM = Problem.of(
750         *     x -> cos(0.5 + sin(x))*cos(x),
751         *     Codecs.ofScalar(DoubleRange.of(0.0, 2.0*PI))
752         * );
753         *
754         * private static final Engine<DoubleGene, Double>
755         * ENGINE = Engine.builder(PROBLEM)
756         *     .optimize(Optimize.MINIMUM)
757         *     .offspringSelector(new RouletteWheelSelector<>())
758         *     .build();
759         *
760         * public static void main(final String[] args) throws IOException {
761         *     // Result of the first evolution run.
762         *     final EvolutionResult<DoubleGene, Double> rescue = ENGINE.stream()
763         *         .limit(Limits.bySteadyFitness(10))
764         *         .collect(EvolutionResult.toBestEvolutionResult());
765         *
766         *     // Save the result of the first run into a file.
767         *     final Path path = Paths.get("result.bin");
768         *     IO.object.write(rescue, path);
769         *
770         *     // Load the previous result and continue evolution.
771         *     \@SuppressWarnings("unchecked")
772         *     final EvolutionResult<DoubleGene, Double> result = ENGINE
773         *         .stream((EvolutionResult<DoubleGene, Double>)IO.object.read(path))
774         *         .limit(Limits.bySteadyFitness(20))
775         *         .collect(EvolutionResult.toBestEvolutionResult());
776         *
777         *     System.out.println(result.getBestPhenotype());
778         * }
779         * }</pre>
780         *
781         * The example above shows how to save an {@link EvolutionResult} from a
782         * first run, save it to disk and continue the evolution.
783         *
784         * @since 3.7
785         *
786         * @param result the previously evolved {@code EvolutionResult}
787         * @return a new evolution stream, which continues a previous one
788         * @throws NullPointerException if the given evolution {@code result} is
789         *         {@code null}
790         */
791        public EvolutionStream<G, C> stream(final EvolutionResult<G, C> result) {
792                return stream(result.getPopulation(), result.getTotalGenerations());
793        }
794
795
796        /* *************************************************************************
797         * Property access methods.
798         **************************************************************************/
799
800        /**
801         * Return the fitness function of the GA engine.
802         *
803         * @return the fitness function
804         */
805        public Function<? super Genotype<G>, ? extends C> getFitnessFunction() {
806                return _fitnessFunction;
807        }
808
809        /**
810         * Return the fitness scaler of the GA engine.
811         *
812         * @return the fitness scaler
813         */
814        public Function<? super C, ? extends C> getFitnessScaler() {
815                return _fitnessScaler;
816        }
817
818        /**
819         * Return the used genotype {@link Factory} of the GA. The genotype factory
820         * is used for creating the initial population and new, random individuals
821         * when needed (as replacement for invalid and/or died genotypes).
822         *
823         * @return the used genotype {@link Factory} of the GA.
824         */
825        public Factory<Genotype<G>> getGenotypeFactory() {
826                return _genotypeFactory;
827        }
828
829        /**
830         * Return the used survivor {@link Selector} of the GA.
831         *
832         * @return the used survivor {@link Selector} of the GA.
833         */
834        public Selector<G, C> getSurvivorsSelector() {
835                return _survivorsSelector;
836        }
837
838        /**
839         * Return the used offspring {@link Selector} of the GA.
840         *
841         * @return the used offspring {@link Selector} of the GA.
842         */
843        public Selector<G, C> getOffspringSelector() {
844                return _offspringSelector;
845        }
846
847        /**
848         * Return the used {@link Alterer} of the GA.
849         *
850         * @return the used {@link Alterer} of the GA.
851         */
852        public Alterer<G, C> getAlterer() {
853                return _alterer;
854        }
855
856        /**
857         * Return the number of selected offsprings.
858         *
859         * @return the number of selected offsprings
860         */
861        public int getOffspringCount() {
862                return _offspringCount;
863        }
864
865        /**
866         * The number of selected survivors.
867         *
868         * @return the number of selected survivors
869         */
870        public int getSurvivorsCount() {
871                return _survivorsCount;
872        }
873
874        /**
875         * Return the number of individuals of a population.
876         *
877         * @return the number of individuals of a population
878         */
879        public int getPopulationSize() {
880                return _offspringCount + _survivorsCount;
881        }
882
883        /**
884         * Return the maximal allowed phenotype age.
885         *
886         * @return the maximal allowed phenotype age
887         */
888        public long getMaximalPhenotypeAge() {
889                return _maximalPhenotypeAge;
890        }
891
892        /**
893         * Return the optimization strategy.
894         *
895         * @return the optimization strategy
896         */
897        public Optimize getOptimize() {
898                return _optimize;
899        }
900
901        /**
902         * Return the {@link Clock} the engine is using for measuring the execution
903         * time.
904         *
905         * @return the clock used for measuring the execution time
906         */
907        public Clock getClock() {
908                return _clock;
909        }
910
911        /**
912         * Return the {@link Executor} the engine is using for executing the
913         * evolution steps.
914         *
915         * @return the executor used for performing the evolution steps
916         */
917        public Executor getExecutor() {
918                return _executor.get();
919        }
920
921
922        /**
923         * Return the maximal number of attempt before the {@code Engine} gives
924         * up creating a valid individual ({@code Phenotype}).
925         *
926         * @since 4.0
927         *
928         * @return the maximal number of {@code Phenotype} creation attempts
929         */
930        public int getIndividualCreationRetries() {
931                return _individualCreationRetries;
932        }
933
934        /**
935         * Return the evolution result mapper.
936         *
937         * @since 4.0
938         *
939         * @return the evolution result mapper
940         */
941        public UnaryOperator<EvolutionResult<G, C>> getMapper() {
942                return _mapper;
943        }
944
945        /* *************************************************************************
946         * Builder methods.
947         **************************************************************************/
948
949        /**
950         * Create a new evolution {@code Engine.Builder} initialized with the values
951         * of the current evolution {@code Engine}. With this method, the evolution
952         * engine can serve as a template for a new one.
953         *
954         * @return a new engine builder
955         */
956        public Builder<G, C> builder() {
957                return new Builder<G, C>(_genotypeFactory, _fitnessFunction)
958                        .alterers(_alterer)
959                        .clock(_clock)
960                        .executor(_executor.get())
961                        .fitnessScaler(_fitnessScaler)
962                        .maximalPhenotypeAge(_maximalPhenotypeAge)
963                        .offspringFraction((double)_offspringCount/(double)getPopulationSize())
964                        .offspringSelector(_offspringSelector)
965                        .optimize(_optimize)
966                        .phenotypeValidator(_validator)
967                        .populationSize(getPopulationSize())
968                        .survivorsSelector(_survivorsSelector)
969                        .individualCreationRetries(_individualCreationRetries)
970                        .mapping(_mapper);
971        }
972
973        /**
974         * Create a new evolution {@code Engine.Builder} for the given
975         * {@link Problem}.
976         *
977         * @since 3.4
978         *
979         * @param problem the problem to be solved by the evolution {@code Engine}
980         * @param <T> the (<i>native</i>) argument type of the problem fitness function
981         * @param <G> the gene type the evolution engine is working with
982         * @param <C> the result type of the fitness function
983         * @return Create a new evolution {@code Engine.Builder}
984         */
985        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
986        Builder<G, C> builder(final Problem<T, G, C> problem) {
987                return builder(problem.fitness(), problem.codec());
988        }
989
990        /**
991         * Create a new evolution {@code Engine.Builder} with the given fitness
992         * function and genotype factory.
993         *
994         * @param ff the fitness function
995         * @param genotypeFactory the genotype factory
996         * @param <G> the gene type
997         * @param <C> the fitness function result type
998         * @return a new engine builder
999         * @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                G extends Gene<?, G>,
1072                C 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 == 0 ?
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}