001/*
002 * Java Genetic Algorithm Library (jenetics-4.3.0).
003 * Copyright (c) 2007-2018 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.Supplier;
036import java.util.function.UnaryOperator;
037import java.util.stream.Stream;
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.require;
051import io.jenetics.util.Copyable;
052import io.jenetics.util.Factory;
053import io.jenetics.util.ISeq;
054import io.jenetics.util.MSeq;
055import io.jenetics.util.NanoClock;
056import io.jenetics.util.Seq;
057
058/**
059 * Genetic algorithm <em>engine</em> which is the main class. The following
060 * example shows the main steps in initializing and executing the GA.
061 *
062 * <pre>{@code
063 * public class RealFunction {
064 *    // Definition of the fitness function.
065 *    private static Double eval(final Genotype<DoubleGene> gt) {
066 *        final double x = gt.getGene().doubleValue();
067 *        return cos(0.5 + sin(x))*cos(x);
068 *    }
069 *
070 *    public static void main(String[] args) {
071 *        // Create/configuring the engine via its builder.
072 *        final Engine<DoubleGene, Double> engine = Engine
073 *            .builder(
074 *                RealFunction::eval,
075 *                DoubleChromosome.of(0.0, 2.0*PI))
076 *            .populationSize(500)
077 *            .optimize(Optimize.MINIMUM)
078 *            .alterers(
079 *                new Mutator<>(0.03),
080 *                new MeanAlterer<>(0.6))
081 *            .build();
082 *
083 *        // Execute the GA (engine).
084 *        final Phenotype<DoubleGene, Double> result = engine.stream()
085 *             // Truncate the evolution stream if no better individual could
086 *             // be found after 5 consecutive generations.
087 *            .limit(bySteadyFitness(5))
088 *             // Terminate the evolution after maximal 100 generations.
089 *            .limit(100)
090 *            .collect(toBestPhenotype());
091 *     }
092 * }
093 * }</pre>
094 *
095 * The architecture allows to decouple the configuration of the engine from the
096 * execution. The {@code Engine} is configured via the {@code Engine.Builder}
097 * class and can't be changed after creation. The actual <i>evolution</i> is
098 * performed by the {@link EvolutionStream}, which is created by the
099 * {@code Engine}.
100 *
101 * @implNote
102 *     This class is thread safe:
103 *     No mutable state is maintained by the engine. Therefore it is save to
104 *     create multiple evolution streams with one engine, which may be actually
105 *     used in different threads.
106 *
107 * @see Engine.Builder
108 * @see EvolutionStart
109 * @see EvolutionResult
110 * @see EvolutionStream
111 * @see EvolutionStatistics
112 * @see Codec
113 *
114 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
115 * @since 3.0
116 * @version 4.1
117 */
118@SuppressWarnings("deprecation")
119public final class Engine<
120        G extends Gene<?, G>,
121        C extends Comparable<? super C>
122>
123        implements
124                Function<EvolutionStart<G, C>, EvolutionResult<G, C>>,
125                EvolutionStreamable<G, C>,
126                EvolutionIterable<G, C>
127{
128
129        // Problem definition.
130        private final Function<? super Genotype<G>, ? extends C> _fitnessFunction;
131        private final Factory<Genotype<G>> _genotypeFactory;
132
133        // Evolution parameters.
134        private final Function<? super C, ? extends C> _fitnessScaler;
135        private final Selector<G, C> _survivorsSelector;
136        private final Selector<G, C> _offspringSelector;
137        private final Alterer<G, C> _alterer;
138        private final Predicate<? super Phenotype<G, C>> _validator;
139        private final Optimize _optimize;
140        private final int _offspringCount;
141        private final int _survivorsCount;
142        private final long _maximalPhenotypeAge;
143
144        // Execution context for concurrent execution of evolving steps.
145        private final TimedExecutor _executor;
146        private final Evaluator<G, C> _evaluator;
147        private final Clock _clock;
148
149        // Additional parameters.
150        private final int _individualCreationRetries;
151        private final UnaryOperator<EvolutionResult<G, C>> _mapper;
152
153
154        /**
155         * Create a new GA engine with the given parameters.
156         *
157         * @param fitnessFunction the fitness function this GA is using.
158         * @param genotypeFactory the genotype factory this GA is working with.
159         * @param fitnessScaler the fitness scaler this GA is using.
160         * @param survivorsSelector the selector used for selecting the survivors
161         * @param offspringSelector the selector used for selecting the offspring
162         * @param alterer the alterer used for altering the offspring
163         * @param validator phenotype validator which can override the default
164         *        implementation the {@link Phenotype#isValid()} method.
165         * @param optimize the kind of optimization (minimize or maximize)
166         * @param offspringCount the number of the offspring individuals
167         * @param survivorsCount the number of the survivor individuals
168         * @param maximalPhenotypeAge the maximal age of an individual
169         * @param executor the executor used for executing the single evolve steps
170         * @param evaluator the population fitness evaluator
171         * @param clock the clock used for calculating the timing results
172         * @param individualCreationRetries the maximal number of attempts for
173         *        creating a valid individual.
174         * @throws NullPointerException if one of the arguments is {@code null}
175         * @throws IllegalArgumentException if the given integer values are smaller
176         *         than one.
177         */
178        Engine(
179                final Function<? super Genotype<G>, ? extends C> fitnessFunction,
180                final Factory<Genotype<G>> genotypeFactory,
181                final Function<? super C, ? extends C> fitnessScaler,
182                final Selector<G, C> survivorsSelector,
183                final Selector<G, C> offspringSelector,
184                final Alterer<G, C> alterer,
185                final Predicate<? super Phenotype<G, C>> validator,
186                final Optimize optimize,
187                final int offspringCount,
188                final int survivorsCount,
189                final long maximalPhenotypeAge,
190                final Executor executor,
191                final Evaluator<G, C> evaluator,
192                final Clock clock,
193                final int individualCreationRetries,
194                final UnaryOperator<EvolutionResult<G, C>> mapper
195        ) {
196                _fitnessFunction = requireNonNull(fitnessFunction);
197                _fitnessScaler = requireNonNull(fitnessScaler);
198                _genotypeFactory = requireNonNull(genotypeFactory);
199                _survivorsSelector = requireNonNull(survivorsSelector);
200                _offspringSelector = requireNonNull(offspringSelector);
201                _alterer = requireNonNull(alterer);
202                _validator = requireNonNull(validator);
203                _optimize = requireNonNull(optimize);
204
205                _offspringCount = require.nonNegative(offspringCount);
206                _survivorsCount = require.nonNegative(survivorsCount);
207                _maximalPhenotypeAge = require.positive(maximalPhenotypeAge);
208
209                _executor = new TimedExecutor(requireNonNull(executor));
210                _evaluator = requireNonNull(evaluator);
211                _clock = requireNonNull(clock);
212
213                if (individualCreationRetries < 0) {
214                        throw new IllegalArgumentException(format(
215                                "Retry count must not be negative: %d",
216                                individualCreationRetries
217                        ));
218                }
219                _individualCreationRetries = individualCreationRetries;
220                _mapper = requireNonNull(mapper);
221        }
222
223        /**
224         * Perform one evolution step with the given {@code population} and
225         * {@code generation}. New phenotypes are created with the fitness function
226         * and fitness scaler defined by this <em>engine</em>
227         * <p>
228         * <em>This method is thread-safe.</em>
229         *
230         * @see #evolve(EvolutionStart)
231         *
232         * @param population the population to evolve
233         * @param generation the current generation; used for calculating the
234         *        phenotype age.
235         * @return the evolution result
236         * @throws java.lang.NullPointerException if the given {@code population} is
237         *         {@code null}
238         * @throws IllegalArgumentException if the given {@code generation} is
239         *         smaller then one
240         */
241        public EvolutionResult<G, C> evolve(
242                final ISeq<Phenotype<G, C>> population,
243                final long generation
244        ) {
245                return evolve(EvolutionStart.of(population, generation));
246        }
247
248        /**
249         * Perform one evolution step with the given evolution {@code start} object
250         * New phenotypes are created with the fitness function and fitness scaler
251         * defined by this <em>engine</em>
252         * <p>
253         * <em>This method is thread-safe.</em>
254         *
255         * @since 3.1
256         * @see #evolve(ISeq, long)
257         *
258         * @param start the evolution start object
259         * @return the evolution result
260         * @throws java.lang.NullPointerException if the given evolution
261         *         {@code start} is {@code null}
262         */
263        public EvolutionResult<G, C> evolve(final EvolutionStart<G, C> start) {
264                final Timer timer = Timer.of(_clock).start();
265
266                // Initial evaluation of the population.
267                final Timer evaluateTimer = Timer.of(_clock).start();
268                final ISeq<Phenotype<G, C>> evalPop =
269                        _evaluator.evaluate(start.getPopulation());
270
271                if (start.getPopulation().size() != evalPop.size()) {
272                        throw new IllegalStateException(format(
273                                "Expected %d individuals, but got %d. " +
274                                "Check your evaluator function.",
275                                start.getPopulation().size(), evalPop.size()
276                        ));
277                }
278
279                evaluateTimer.stop();
280
281                // Select the offspring population.
282                final CompletableFuture<TimedResult<ISeq<Phenotype<G, C>>>> offspring =
283                        _executor.async(() ->
284                                selectOffspring(evalPop),
285                                _clock
286                        );
287
288                // Select the survivor population.
289                final CompletableFuture<TimedResult<ISeq<Phenotype<G, C>>>> survivors =
290                        _executor.async(() ->
291                                selectSurvivors(evalPop),
292                                _clock
293                        );
294
295                // Altering the offspring population.
296                final CompletableFuture<TimedResult<AltererResult<G, C>>> alteredOffspring =
297                        _executor.thenApply(offspring, p ->
298                                _alterer.alter(p.result, start.getGeneration()),
299                                _clock
300                        );
301
302                // Filter and replace invalid and old survivor individuals.
303                final CompletableFuture<TimedResult<FilterResult<G, C>>> filteredSurvivors =
304                        _executor.thenApply(survivors, pop ->
305                                filter(pop.result, start.getGeneration()),
306                                _clock
307                        );
308
309                // Filter and replace invalid and old offspring individuals.
310                final CompletableFuture<TimedResult<FilterResult<G, C>>> filteredOffspring =
311                        _executor.thenApply(alteredOffspring, pop ->
312                                filter(pop.result.getPopulation(), start.getGeneration()),
313                                _clock
314                        );
315
316                // Combining survivors and offspring to the new population.
317                final CompletableFuture<ISeq<Phenotype<G, C>>> population =
318                        filteredSurvivors.thenCombineAsync(filteredOffspring, (s, o) ->
319                                        ISeq.of(s.result.population.append(o.result.population)),
320                                _executor.get()
321                        );
322
323                // Evaluate the fitness-function and wait for result.
324                final ISeq<Phenotype<G, C>> pop = population.join();
325                final TimedResult<ISeq<Phenotype<G, C>>> result = TimedResult
326                        .of(() -> _evaluator.evaluate(pop), _clock)
327                        .get();
328
329
330                final EvolutionDurations durations = EvolutionDurations.of(
331                        offspring.join().duration,
332                        survivors.join().duration,
333                        alteredOffspring.join().duration,
334                        filteredOffspring.join().duration,
335                        filteredSurvivors.join().duration,
336                        result.duration.plus(evaluateTimer.getTime()),
337                        timer.stop().getTime()
338                );
339
340                final int killCount =
341                        filteredOffspring.join().result.killCount +
342                        filteredSurvivors.join().result.killCount;
343
344                final int invalidCount =
345                        filteredOffspring.join().result.invalidCount +
346                        filteredSurvivors.join().result.invalidCount;
347
348                return _mapper.apply(
349                        EvolutionResult.of(
350                                _optimize,
351                                result.result,
352                                start.getGeneration(),
353                                durations,
354                                killCount,
355                                invalidCount,
356                                alteredOffspring.join().result.getAlterations()
357                        )
358                );
359        }
360
361        /**
362         * This method is an <i>alias</i> for the {@link #evolve(EvolutionStart)}
363         * method.
364         *
365         * @since 3.1
366         */
367        @Override
368        public EvolutionResult<G, C> apply(final EvolutionStart<G, C> start) {
369                return evolve(start);
370        }
371
372        // Selects the survivors population. A new population object is returned.
373        private ISeq<Phenotype<G, C>>
374        selectSurvivors(final ISeq<Phenotype<G, C>> population) {
375                return _survivorsCount > 0
376                        ?_survivorsSelector.select(population, _survivorsCount, _optimize)
377                        : ISeq.empty();
378        }
379
380        // Selects the offspring population. A new population object is returned.
381        private ISeq<Phenotype<G, C>>
382        selectOffspring(final ISeq<Phenotype<G, C>> population) {
383                return _offspringCount > 0
384                        ? _offspringSelector.select(population, _offspringCount, _optimize)
385                        : ISeq.empty();
386        }
387
388        // Filters out invalid and old individuals. Filtering is done in place.
389        private FilterResult<G, C> filter(
390                final Seq<Phenotype<G, C>> population,
391                final long generation
392        ) {
393                int killCount = 0;
394                int invalidCount = 0;
395
396                final MSeq<Phenotype<G, C>> pop = MSeq.of(population);
397                for (int i = 0, n = pop.size(); i < n; ++i) {
398                        final Phenotype<G, C> individual = pop.get(i);
399
400                        if (!_validator.test(individual)) {
401                                pop.set(i, newPhenotype(generation));
402                                ++invalidCount;
403                        } else if (individual.getAge(generation) > _maximalPhenotypeAge) {
404                                pop.set(i, newPhenotype(generation));
405                                ++killCount;
406                        }
407                }
408
409                return new FilterResult<>(pop.toISeq(), killCount, invalidCount);
410        }
411
412        // Create a new and valid phenotype
413        private Phenotype<G, C> newPhenotype(final long generation) {
414                int count = 0;
415                Phenotype<G, C> phenotype;
416                do {
417                        phenotype = Phenotype.of(
418                                _genotypeFactory.newInstance(),
419                                generation,
420                                _fitnessFunction,
421                                _fitnessScaler
422                        );
423                } while (++count < _individualCreationRetries &&
424                                !_validator.test(phenotype));
425
426                return phenotype;
427        }
428
429
430        /* *************************************************************************
431         * Evolution Stream/Iterator creation.
432         **************************************************************************/
433
434        @Deprecated
435        @Override
436        public Iterator<EvolutionResult<G, C>>
437        iterator(final Supplier<EvolutionStart<G, C>> start) {
438                return new EvolutionIterator<>(evolutionStart(start), this::evolve);
439        }
440
441        @Deprecated
442        @Override
443        public Iterator<EvolutionResult<G, C>> iterator(final EvolutionInit<G> init) {
444                return iterator(evolutionStart(init));
445        }
446
447        @Override
448        public EvolutionStream<G, C>
449        stream(final Supplier<EvolutionStart<G, C>> start) {
450                return EvolutionStream.of(evolutionStart(start), this::evolve);
451        }
452
453        @Override
454        public EvolutionStream<G, C> stream(final EvolutionInit<G> init) {
455                return stream(evolutionStart(init));
456        }
457
458        private Supplier<EvolutionStart<G, C>>
459        evolutionStart(final Supplier<EvolutionStart<G, C>> start) {
460                return () -> {
461                        final EvolutionStart<G, C> es = start.get();
462                        final ISeq<Phenotype<G, C>> population = es.getPopulation();
463                        final long generation = es.getGeneration();
464
465                        final Stream<Phenotype<G, C>> stream = Stream.concat(
466                                population.stream().map(this::toFixedPhenotype),
467                                Stream.generate(() -> newPhenotype(generation))
468                        );
469
470                        final ISeq<Phenotype<G, C>> pop = stream
471                                .limit(getPopulationSize())
472                                .collect(ISeq.toISeq());
473
474                        return EvolutionStart.of(pop, generation);
475                };
476        }
477
478        private Phenotype<G, C> toFixedPhenotype(final Phenotype<G, C> pt) {
479                return
480                        pt.getFitnessFunction() == _fitnessFunction &&
481                        pt.getFitnessScaler() == _fitnessScaler
482                                ? pt
483                                : pt.newInstance(
484                                        pt.getGeneration(),
485                                        _fitnessFunction,
486                                        _fitnessScaler
487                                );
488        }
489
490        private Supplier<EvolutionStart<G, C>>
491        evolutionStart(final EvolutionInit<G> init) {
492                return evolutionStart(() -> EvolutionStart.of(
493                        init.getPopulation()
494                                .map(gt -> Phenotype.of(
495                                        gt,
496                                        init.getGeneration(),
497                                        _fitnessFunction,
498                                        _fitnessScaler)
499                                ),
500                        init.getGeneration())
501                );
502        }
503
504        /* *************************************************************************
505         * Property access methods.
506         **************************************************************************/
507
508        /**
509         * Return the fitness function of the GA engine.
510         *
511         * @return the fitness function
512         */
513        public Function<? super Genotype<G>, ? extends C> getFitnessFunction() {
514                return _fitnessFunction;
515        }
516
517        /**
518         * Return the fitness scaler of the GA engine.
519         *
520         * @return the fitness scaler
521         *
522         * @deprecated The fitness scaler will be remove in a future version.
523         */
524        @Deprecated
525        public Function<? super C, ? extends C> getFitnessScaler() {
526                return _fitnessScaler;
527        }
528
529        /**
530         * Return the used genotype {@link Factory} of the GA. The genotype factory
531         * is used for creating the initial population and new, random individuals
532         * when needed (as replacement for invalid and/or died genotypes).
533         *
534         * @return the used genotype {@link Factory} of the GA.
535         */
536        public Factory<Genotype<G>> getGenotypeFactory() {
537                return _genotypeFactory;
538        }
539
540        /**
541         * Return the used survivor {@link Selector} of the GA.
542         *
543         * @return the used survivor {@link Selector} of the GA.
544         */
545        public Selector<G, C> getSurvivorsSelector() {
546                return _survivorsSelector;
547        }
548
549        /**
550         * Return the used offspring {@link Selector} of the GA.
551         *
552         * @return the used offspring {@link Selector} of the GA.
553         */
554        public Selector<G, C> getOffspringSelector() {
555                return _offspringSelector;
556        }
557
558        /**
559         * Return the used {@link Alterer} of the GA.
560         *
561         * @return the used {@link Alterer} of the GA.
562         */
563        public Alterer<G, C> getAlterer() {
564                return _alterer;
565        }
566
567        /**
568         * Return the number of selected offsprings.
569         *
570         * @return the number of selected offsprings
571         */
572        public int getOffspringCount() {
573                return _offspringCount;
574        }
575
576        /**
577         * The number of selected survivors.
578         *
579         * @return the number of selected survivors
580         */
581        public int getSurvivorsCount() {
582                return _survivorsCount;
583        }
584
585        /**
586         * Return the number of individuals of a population.
587         *
588         * @return the number of individuals of a population
589         */
590        public int getPopulationSize() {
591                return _offspringCount + _survivorsCount;
592        }
593
594        /**
595         * Return the maximal allowed phenotype age.
596         *
597         * @return the maximal allowed phenotype age
598         */
599        public long getMaximalPhenotypeAge() {
600                return _maximalPhenotypeAge;
601        }
602
603        /**
604         * Return the optimization strategy.
605         *
606         * @return the optimization strategy
607         */
608        public Optimize getOptimize() {
609                return _optimize;
610        }
611
612        /**
613         * Return the {@link Clock} the engine is using for measuring the execution
614         * time.
615         *
616         * @return the clock used for measuring the execution time
617         */
618        public Clock getClock() {
619                return _clock;
620        }
621
622        /**
623         * Return the {@link Executor} the engine is using for executing the
624         * evolution steps.
625         *
626         * @return the executor used for performing the evolution steps
627         */
628        public Executor getExecutor() {
629                return _executor.get();
630        }
631
632
633        /**
634         * Return the maximal number of attempt before the {@code Engine} gives
635         * up creating a valid individual ({@code Phenotype}).
636         *
637         * @since 4.0
638         *
639         * @return the maximal number of {@code Phenotype} creation attempts
640         */
641        public int getIndividualCreationRetries() {
642                return _individualCreationRetries;
643        }
644
645        /**
646         * Return the evolution result mapper.
647         *
648         * @since 4.0
649         *
650         * @return the evolution result mapper
651         */
652        public UnaryOperator<EvolutionResult<G, C>> getMapper() {
653                return _mapper;
654        }
655
656        /* *************************************************************************
657         * Builder methods.
658         **************************************************************************/
659
660        /**
661         * Create a new evolution {@code Engine.Builder} initialized with the values
662         * of the current evolution {@code Engine}. With this method, the evolution
663         * engine can serve as a template for a new one.
664         *
665         * @return a new engine builder
666         */
667        public Builder<G, C> builder() {
668                return new Builder<G, C>(_genotypeFactory, _fitnessFunction)
669                        .alterers(_alterer)
670                        .clock(_clock)
671                        .evaluator(_evaluator)
672                        .executor(_executor.get())
673                        .fitnessScaler(_fitnessScaler)
674                        .maximalPhenotypeAge(_maximalPhenotypeAge)
675                        .offspringFraction((double)_offspringCount/(double)getPopulationSize())
676                        .offspringSelector(_offspringSelector)
677                        .optimize(_optimize)
678                        .phenotypeValidator(_validator)
679                        .populationSize(getPopulationSize())
680                        .survivorsSelector(_survivorsSelector)
681                        .individualCreationRetries(_individualCreationRetries)
682                        .mapping(_mapper);
683        }
684
685        /**
686         * Create a new evolution {@code Engine.Builder} for the given
687         * {@link Problem}.
688         *
689         * @since 3.4
690         *
691         * @param problem the problem to be solved by the evolution {@code Engine}
692         * @param <T> the (<i>native</i>) argument type of the problem fitness function
693         * @param <G> the gene type the evolution engine is working with
694         * @param <C> the result type of the fitness function
695         * @return Create a new evolution {@code Engine.Builder}
696         */
697        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
698        Builder<G, C> builder(final Problem<T, G, C> problem) {
699                return builder(problem.fitness(), problem.codec());
700        }
701
702        /**
703         * Create a new evolution {@code Engine.Builder} with the given fitness
704         * function and genotype factory.
705         *
706         * @param ff the fitness function
707         * @param genotypeFactory the genotype factory
708         * @param <G> the gene type
709         * @param <C> the fitness function result type
710         * @return a new engine builder
711         * @throws java.lang.NullPointerException if one of the arguments is
712         *         {@code null}.
713         */
714        public static <G extends Gene<?, G>, C extends Comparable<? super C>>
715        Builder<G, C> builder(
716                final Function<? super Genotype<G>, ? extends C> ff,
717                final Factory<Genotype<G>> genotypeFactory
718        ) {
719                return new Builder<>(genotypeFactory, ff);
720        }
721
722        /**
723         * Create a new evolution {@code Engine.Builder} with the given fitness
724         * function and chromosome templates.
725         *
726         * @param ff the fitness function
727         * @param chromosome the first chromosome
728         * @param chromosomes the chromosome templates
729         * @param <G> the gene type
730         * @param <C> the fitness function result type
731         * @return a new engine builder
732         * @throws java.lang.NullPointerException if one of the arguments is
733         *         {@code null}.
734         */
735        @SafeVarargs
736        public static <G extends Gene<?, G>, C extends Comparable<? super C>>
737        Builder<G, C> builder(
738                final Function<? super Genotype<G>, ? extends C> ff,
739                final Chromosome<G> chromosome,
740                final Chromosome<G>... chromosomes
741        ) {
742                return new Builder<>(Genotype.of(chromosome, chromosomes), ff);
743        }
744
745        /**
746         * Create a new evolution {@code Engine.Builder} with the given fitness
747         * function and problem {@code codec}.
748         *
749         * @since 3.2
750         *
751         * @param ff the fitness function
752         * @param codec the problem codec
753         * @param <T> the fitness function input type
754         * @param <C> the fitness function result type
755         * @param <G> the gene type
756         * @return a new engine builder
757         * @throws java.lang.NullPointerException if one of the arguments is
758         *         {@code null}.
759         */
760        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
761        Builder<G, C> builder(
762                final Function<? super T, ? extends C> ff,
763                final Codec<T, G> codec
764        ) {
765                return builder(ff.compose(codec.decoder()), codec.encoding());
766        }
767
768
769        /* *************************************************************************
770         * Inner classes
771         **************************************************************************/
772
773
774        /**
775         * This interface allows to define different strategies for evaluating the
776         * fitness functions of a given population. <em>Normally</em>, there is no
777         * need for <em>overriding</em> the default evaluation strategy, but it might
778         * be necessary if you have performance problems and a <em>batched</em>
779         * fitness evaluation would solve the problem.
780         * <p>
781         * The implementer is free to do the evaluation <em>in place</em>, or create
782         * new {@link Phenotype} instance and return the newly created one. A simple
783         * serial evaluator can easily implemented:
784         *
785         * <pre>{@code
786         * final Evaluator<G, C> evaluator = population -> {
787         *     population.forEach(Phenotype::evaluate);
788         *     return population.asISeq();
789         * };
790         * }</pre>
791         *
792         * @implSpec
793         * The size of the returned, evaluated, phenotype sequence must be exactly
794         * the size of the input phenotype sequence. It is allowed to return the
795         * input sequence, after evaluation, as well a newly created one.
796         *
797         * @apiNote
798         * This interface is an <em>advanced</em> {@code Engine} configuration
799         * feature, which should be only used when there is a performance gain from
800         * implementing a different evaluation strategy. Another use case is, when
801         * the fitness value of an individual also depends on the current composition
802         * of the population.
803         *
804         * @see GenotypeEvaluator
805         * @see Engine.Builder#evaluator(Engine.Evaluator)
806         *
807         * @param <G> the gene type
808         * @param <C> the fitness result type
809         *
810         * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
811         * @version 4.2
812         * @since 4.2
813         */
814        @FunctionalInterface
815        public static interface Evaluator<
816                G extends Gene<?, G>,
817                C extends Comparable<? super C>
818        > {
819
820                /**
821                 * Evaluates the fitness values of the given {@code population}. The
822                 * given {@code population} might contain already evaluated individuals.
823                 * It is the responsibility of the implementer to filter out already
824                 * evaluated individuals, if desired.
825                 *
826                 * @param population the population to evaluate
827                 * @return the evaluated population. Implementers are free to return the
828                 *         the input population or a newly created one.
829                 */
830                public ISeq<Phenotype<G, C>> evaluate(final Seq<Phenotype<G, C>> population);
831
832                /**
833                 * Create a new phenotype evaluator from a given genotype {@code evaluator}.
834                 *
835                 * @implNote
836                 * The returned {@link Evaluator} will only forward <em>un</em>-evaluated
837                 * individuals to the given genotype {@code evaluator}. This means, that
838                 * already evaluated individuals are filtered from the population, which
839                 * is then forwarded to the underlying genotype {@code evaluator}.
840                 *
841                 * @param evaluator the genotype evaluator
842                 * @param <G> the gene type
843                 * @param <C> the fitness result type
844                 * @return a <em>normal</em> phenotype evaluator from the given genotype
845                 *         evaluator
846                 * @throws NullPointerException if the given {@code evaluator} is
847                 *         {@code null}
848                 */
849                public static <G extends Gene<?, G>, C extends Comparable<? super C>>
850                Evaluator<G, C> of(final GenotypeEvaluator<G, C> evaluator) {
851                        requireNonNull(evaluator);
852
853                        return population -> {
854                                final ISeq<Genotype<G>> genotypes = population.stream()
855                                        .filter(pt -> !pt.isEvaluated())
856                                        .map(Phenotype::getGenotype)
857                                        .collect(ISeq.toISeq());
858
859                                if (genotypes.nonEmpty()) {
860                                        final ISeq<C> results = evaluator.evaluate(
861                                                genotypes,
862                                                population.get(0).getFitnessFunction()
863                                        );
864
865                                        if (genotypes.size() != results.size()) {
866                                                throw new IllegalStateException(format(
867                                                        "Expected %d results, but got %d. " +
868                                                        "Check your evaluator function.",
869                                                        genotypes.size(), results.size()
870                                                ));
871                                        }
872
873                                        final MSeq<Phenotype<G, C>> evaluated = population.asMSeq();
874                                        for (int i = 0, j = 0; i < evaluated.length(); ++i) {
875                                                if (!population.get(i).isEvaluated()) {
876                                                        evaluated.set(
877                                                                i,
878                                                                population.get(i).withFitness(results.get(j++))
879                                                        );
880                                                }
881                                        }
882
883                                        return evaluated.toISeq();
884                                } else {
885                                        return population.asISeq();
886                                }
887                        };
888                }
889
890        }
891
892        /**
893         * This interface gives a different possibility in evaluating the fitness
894         * values of a population. Sometimes it is necessary (mostly for performance
895         * reason) to calculate the fitness for the whole population at once. This
896         * interface allows you to do so. A simple serial evaluator can easily
897         * implemented:
898         *
899         * <pre>{@code
900         * final GenotypeEvaluator<G, C> gte = (g, f) -> g.map(f).asISeq()
901         * final Evaluator<G, C> evaluator = Evaluator.of(gte);
902         * }</pre>
903         *
904         * @implSpec
905         * The size of the returned result sequence must be exactly the size of the
906         * input genotype sequence.
907         *
908         * @apiNote
909         * This interface is an <em>advanced</em> {@code Engine} configuration
910         * feature, which should be only used when there is a performance gain from
911         * implementing a different evaluation strategy.
912         *
913         * @see Evaluator
914         * @see Engine.Builder#evaluator(Engine.GenotypeEvaluator)
915         *
916         * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
917         * @version 4.2
918         * @since 4.2
919         */
920        @FunctionalInterface
921        public static interface GenotypeEvaluator<
922                G extends Gene<?, G>,
923                C extends Comparable<? super C>
924        > {
925
926                /**
927                 * Calculate the fitness values for the given sequence of genotypes.
928                 *
929                 * @see Engine.Evaluator#of(Engine.GenotypeEvaluator)
930                 *
931                 * @param genotypes the genotypes to evaluate the fitness value for
932                 * @param function the fitness function
933                 * @return the fitness values for the given {@code genotypes} The length
934                 *         of the fitness result sequence must match with the size of
935                 *         the given {@code genotypes}.
936                 */
937                public ISeq<C> evaluate(
938                        final Seq<Genotype<G>> genotypes,
939                        final Function<? super Genotype<G>, ? extends C> function
940                );
941
942        }
943
944
945        /**
946         * Builder class for building GA {@code Engine} instances.
947         *
948         * @see Engine
949         *
950         * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
951         * @since 3.0
952         * @version 4.0
953         */
954        public static final class Builder<
955                G extends Gene<?, G>,
956                C extends Comparable<? super C>
957        >
958                implements Copyable<Builder<G, C>>
959        {
960
961                // No default values for this properties.
962                private Function<? super Genotype<G>, ? extends C> _fitnessFunction;
963                private Factory<Genotype<G>> _genotypeFactory;
964
965                // This are the properties which default values.
966                private Function<? super C, ? extends C> _fitnessScaler = a -> a;
967                private Selector<G, C> _survivorsSelector = new TournamentSelector<>(3);
968                private Selector<G, C> _offspringSelector = new TournamentSelector<>(3);
969                private Alterer<G, C> _alterer = Alterer.of(
970                        new SinglePointCrossover<G, C>(0.2),
971                        new Mutator<>(0.15)
972                );
973                private Predicate<? super Phenotype<G, C>> _validator = Phenotype::isValid;
974                private Optimize _optimize = Optimize.MAXIMUM;
975                private double _offspringFraction = 0.6;
976                private int _populationSize = 50;
977                private long _maximalPhenotypeAge = 70;
978
979                // Engine execution environment.
980                private Executor _executor = ForkJoinPool.commonPool();
981                private Clock _clock = NanoClock.systemUTC();
982                private Evaluator<G, C> _evaluator;
983
984                private int _individualCreationRetries = 10;
985                private UnaryOperator<EvolutionResult<G, C>> _mapper = r -> r;
986
987                private Builder(
988                        final Factory<Genotype<G>> genotypeFactory,
989                        final Function<? super Genotype<G>, ? extends C> fitnessFunction
990                ) {
991                        _genotypeFactory = requireNonNull(genotypeFactory);
992                        _fitnessFunction = requireNonNull(fitnessFunction);
993                }
994
995                /**
996                 * Set the fitness function of the evolution {@code Engine}.
997                 *
998                 * @param function the fitness function to use in the GA {@code Engine}
999                 * @return {@code this} builder, for command chaining
1000                 */
1001                public Builder<G, C> fitnessFunction(
1002                        final Function<? super Genotype<G>, ? extends C> function
1003                ) {
1004                        _fitnessFunction = requireNonNull(function);
1005                        return this;
1006                }
1007
1008                /**
1009                 * Set the fitness scaler of the evolution {@code Engine}. <i>Default
1010                 * value is set to the identity function.</i>
1011                 *
1012                 * @param scaler the fitness scale to use in the GA {@code Engine}
1013                 * @return {@code this} builder, for command chaining
1014                 *
1015                 * @deprecated The fitness scaler will be remove in a future version.
1016                 */
1017                @Deprecated
1018                public Builder<G, C> fitnessScaler(
1019                        final Function<? super C, ? extends C> scaler
1020                ) {
1021                        _fitnessScaler = requireNonNull(scaler);
1022                        return this;
1023                }
1024
1025                /**
1026                 * The genotype factory used for creating new individuals.
1027                 *
1028                 * @param genotypeFactory the genotype factory for creating new
1029                 *        individuals.
1030                 * @return {@code this} builder, for command chaining
1031                 */
1032                public Builder<G, C> genotypeFactory(
1033                        final Factory<Genotype<G>> genotypeFactory
1034                ) {
1035                        _genotypeFactory = requireNonNull(genotypeFactory);
1036                        return this;
1037                }
1038
1039                /**
1040                 * The selector used for selecting the offspring population. <i>Default
1041                 * values is set to {@code TournamentSelector<>(3)}.</i>
1042                 *
1043                 * @param selector used for selecting the offspring population
1044                 * @return {@code this} builder, for command chaining
1045                 */
1046                public Builder<G, C> offspringSelector(
1047                        final Selector<G, C> selector
1048                ) {
1049                        _offspringSelector = requireNonNull(selector);
1050                        return this;
1051                }
1052
1053                /**
1054                 * The selector used for selecting the survivors population. <i>Default
1055                 * values is set to {@code TournamentSelector<>(3)}.</i>
1056                 *
1057                 * @param selector used for selecting survivors population
1058                 * @return {@code this} builder, for command chaining
1059                 */
1060                public Builder<G, C> survivorsSelector(
1061                        final Selector<G, C> selector
1062                ) {
1063                        _survivorsSelector = requireNonNull(selector);
1064                        return this;
1065                }
1066
1067                /**
1068                 * The selector used for selecting the survivors and offspring
1069                 * population. <i>Default values is set to
1070                 * {@code TournamentSelector<>(3)}.</i>
1071                 *
1072                 * @param selector used for selecting survivors and offspring population
1073                 * @return {@code this} builder, for command chaining
1074                 */
1075                public Builder<G, C> selector(final Selector<G, C> selector) {
1076                        _offspringSelector = requireNonNull(selector);
1077                        _survivorsSelector = requireNonNull(selector);
1078                        return this;
1079                }
1080
1081                /**
1082                 * The alterers used for alter the offspring population. <i>Default
1083                 * values is set to {@code new SinglePointCrossover<>(0.2)} followed by
1084                 * {@code new Mutator<>(0.15)}.</i>
1085                 *
1086                 * @param first the first alterer used for alter the offspring
1087                 *        population
1088                 * @param rest the rest of the alterers used for alter the offspring
1089                 *        population
1090                 * @return {@code this} builder, for command chaining
1091                 * @throws java.lang.NullPointerException if one of the alterers is
1092                 *         {@code null}.
1093                 */
1094                @SafeVarargs
1095                public final Builder<G, C> alterers(
1096                        final Alterer<G, C> first,
1097                        final Alterer<G, C>... rest
1098                ) {
1099                        requireNonNull(first);
1100                        Stream.of(rest).forEach(Objects::requireNonNull);
1101
1102                        _alterer = rest.length == 0
1103                                ? first
1104                                : Alterer.of(rest).compose(first);
1105
1106                        return this;
1107                }
1108
1109                /**
1110                 * The phenotype validator used for detecting invalid individuals.
1111                 * Alternatively it is also possible to set the genotype validator with
1112                 * {@link #genotypeFactory(Factory)}, which will replace any
1113                 * previously set phenotype validators.
1114                 *
1115                 * <p><i>Default value is set to {@code Phenotype::isValid}.</i></p>
1116                 *
1117                 * @since 3.1
1118                 *
1119                 * @see #genotypeValidator(Predicate)
1120                 *
1121                 * @param validator the {@code validator} used for validating the
1122                 *        individuals (phenotypes).
1123                 * @return {@code this} builder, for command chaining
1124                 * @throws java.lang.NullPointerException if the {@code validator} is
1125                 *         {@code null}.
1126                 */
1127                public Builder<G, C> phenotypeValidator(
1128                        final Predicate<? super Phenotype<G, C>> validator
1129                ) {
1130                        _validator = requireNonNull(validator);
1131                        return this;
1132                }
1133
1134                /**
1135                 * The genotype validator used for detecting invalid individuals.
1136                 * Alternatively it is also possible to set the phenotype validator with
1137                 * {@link #phenotypeValidator(Predicate)}, which will replace any
1138                 * previously set genotype validators.
1139                 *
1140                 * <p><i>Default value is set to {@code Genotype::isValid}.</i></p>
1141                 *
1142                 * @since 3.1
1143                 *
1144                 * @see #phenotypeValidator(Predicate)
1145                 *
1146                 * @param validator the {@code validator} used for validating the
1147                 *        individuals (genotypes).
1148                 * @return {@code this} builder, for command chaining
1149                 * @throws java.lang.NullPointerException if the {@code validator} is
1150                 *         {@code null}.
1151                 */
1152                public Builder<G, C> genotypeValidator(
1153                        final Predicate<? super Genotype<G>> validator
1154                ) {
1155                        requireNonNull(validator);
1156
1157                        _validator = pt -> validator.test(pt.getGenotype());
1158                        return this;
1159                }
1160
1161                /**
1162                 * The optimization strategy used by the engine. <i>Default values is
1163                 * set to {@code Optimize.MAXIMUM}.</i>
1164                 *
1165                 * @param optimize the optimization strategy used by the engine
1166                 * @return {@code this} builder, for command chaining
1167                 */
1168                public Builder<G, C> optimize(final Optimize optimize) {
1169                        _optimize = requireNonNull(optimize);
1170                        return this;
1171                }
1172
1173                /**
1174                 * Set to a fitness maximizing strategy.
1175                 *
1176                 * @since 3.4
1177                 *
1178                 * @return {@code this} builder, for command chaining
1179                 */
1180                public Builder<G, C> maximizing() {
1181                        return optimize(Optimize.MAXIMUM);
1182                }
1183
1184                /**
1185                 * Set to a fitness minimizing strategy.
1186                 *
1187                 * @since 3.4
1188                 *
1189                 * @return {@code this} builder, for command chaining
1190                 */
1191                public Builder<G, C> minimizing() {
1192                        return optimize(Optimize.MINIMUM);
1193                }
1194
1195                /**
1196                 * The offspring fraction. <i>Default values is set to {@code 0.6}.</i>
1197                 * This method call is equivalent to
1198                 * {@code survivorsFraction(1 - offspringFraction)} and will override
1199                 * any previously set survivors-fraction.
1200                 *
1201                 * @see #survivorsFraction(double)
1202                 *
1203                 * @param fraction the offspring fraction
1204                 * @return {@code this} builder, for command chaining
1205                 * @throws java.lang.IllegalArgumentException if the fraction is not
1206                 *         within the range [0, 1].
1207                 */
1208                public Builder<G, C> offspringFraction(final double fraction) {
1209                        _offspringFraction = probability(fraction);
1210                        return this;
1211                }
1212
1213                /**
1214                 * The survivors fraction. <i>Default values is set to {@code 0.4}.</i>
1215                 * This method call is equivalent to
1216                 * {@code offspringFraction(1 - survivorsFraction)} and will override
1217                 * any previously set offspring-fraction.
1218                 *
1219                 * @since 3.8
1220                 *
1221                 * @see #offspringFraction(double)
1222                 *
1223                 * @param fraction the survivors fraction
1224                 * @return {@code this} builder, for command chaining
1225                 * @throws java.lang.IllegalArgumentException if the fraction is not
1226                 *         within the range [0, 1].
1227                 */
1228                public Builder<G, C> survivorsFraction(final double fraction) {
1229                        _offspringFraction = 1.0 - probability(fraction);
1230                        return this;
1231                }
1232
1233                /**
1234                 * The number of offspring individuals.
1235                 *
1236                 * @since 3.8
1237                 *
1238                 * @param size the number of offspring individuals.
1239                 * @return {@code this} builder, for command chaining
1240                 * @throws java.lang.IllegalArgumentException if the size is not
1241                 *         within the range [0, population-size].
1242                 */
1243                public Builder<G, C> offspringSize(final int size) {
1244                        if (size < 0) {
1245                                throw new IllegalArgumentException(format(
1246                                        "Offspring size must be greater or equal zero, but was %s.",
1247                                        size
1248                                ));
1249                        }
1250
1251                        return offspringFraction((double)size/(double)_populationSize);
1252                }
1253
1254                /**
1255                 * The number of survivors.
1256                 *
1257                 * @since 3.8
1258                 *
1259                 * @param size the number of survivors.
1260                 * @return {@code this} builder, for command chaining
1261                 * @throws java.lang.IllegalArgumentException if the size is not
1262                 *         within the range [0, population-size].
1263                 */
1264                public Builder<G, C> survivorsSize(final int size) {
1265                        if (size < 0) {
1266                                throw new IllegalArgumentException(format(
1267                                        "Survivors must be greater or equal zero, but was %s.",
1268                                        size
1269                                ));
1270                        }
1271
1272                        return survivorsFraction((double)size/(double)_populationSize);
1273                }
1274
1275                /**
1276                 * The number of individuals which form the population. <i>Default
1277                 * values is set to {@code 50}.</i>
1278                 *
1279                 * @param size the number of individuals of a population
1280                 * @return {@code this} builder, for command chaining
1281                 * @throws java.lang.IllegalArgumentException if {@code size < 1}
1282                 */
1283                public Builder<G, C> populationSize(final int size) {
1284                        if (size < 1) {
1285                                throw new IllegalArgumentException(format(
1286                                        "Population size must be greater than zero, but was %s.",
1287                                        size
1288                                ));
1289                        }
1290                        _populationSize = size;
1291                        return this;
1292                }
1293
1294                /**
1295                 * The maximal allowed age of a phenotype. <i>Default values is set to
1296                 * {@code 70}.</i>
1297                 *
1298                 * @param age the maximal phenotype age
1299                 * @return {@code this} builder, for command chaining
1300                 * @throws java.lang.IllegalArgumentException if {@code age < 1}
1301                 */
1302                public Builder<G, C> maximalPhenotypeAge(final long age) {
1303                        if (age < 1) {
1304                                throw new IllegalArgumentException(format(
1305                                        "Phenotype age must be greater than one, but was %s.", age
1306                                ));
1307                        }
1308                        _maximalPhenotypeAge = age;
1309                        return this;
1310                }
1311
1312                /**
1313                 * The executor used by the engine.
1314                 *
1315                 * @param executor the executor used by the engine
1316                 * @return {@code this} builder, for command chaining
1317                 */
1318                public Builder<G, C> executor(final Executor executor) {
1319                        _executor = requireNonNull(executor);
1320                        return this;
1321                }
1322
1323                /**
1324                 * The clock used for calculating the execution durations.
1325                 *
1326                 * @param clock the clock used for calculating the execution durations
1327                 * @return {@code this} builder, for command chaining
1328                 */
1329                public Builder<G, C> clock(final Clock clock) {
1330                        _clock = requireNonNull(clock);
1331                        return this;
1332                }
1333
1334                /**
1335                 * The phenotype evaluator allows to change the evaluation strategy.
1336                 * By default, the population is evaluated concurrently using the
1337                 * defined {@link Executor} implementation.
1338                 *
1339                 * @apiNote
1340                 * This is an <em>advanced</em> {@code Engine} configuration feature,
1341                 * which should be only used when there is a performance gain from
1342                 * implementing a different evaluation strategy.
1343                 *
1344                 * @since 4.2
1345                 *
1346                 * @param evaluator the population evaluation strategy
1347                 * @return {@code this} builder, for command chaining
1348                 */
1349                public Builder<G, C> evaluator(final Evaluator<G, C> evaluator) {
1350                        _evaluator = requireNonNull(evaluator);
1351                        return this;
1352                }
1353
1354                /**
1355                 * Setting the <em>genotype</em> evaluator used for evaluating the
1356                 * fitness function of the population.
1357                 *
1358                 * @apiNote
1359                 * This is an <em>advanced</em> {@code Engine} configuration feature,
1360                 * which should be only used when there is a performance gain from
1361                 * implementing a different evaluation strategy.
1362                 *
1363                 * @since 4.2
1364                 *
1365                 * @param evaluator the genotype evaluator
1366                 * @return {@code this} builder, for command chaining
1367                 */
1368                public Builder<G, C> evaluator(final GenotypeEvaluator<G, C> evaluator) {
1369                        _evaluator = Evaluator.of(evaluator);
1370                        return this;
1371                }
1372
1373                /**
1374                 * The maximal number of attempt before the {@code Engine} gives up
1375                 * creating a valid individual ({@code Phenotype}). <i>Default values is
1376                 * set to {@code 10}.</i>
1377                 *
1378                 * @since 3.1
1379                 *
1380                 * @param retries the maximal retry count
1381                 * @throws IllegalArgumentException if the given retry {@code count} is
1382                 *         smaller than zero.
1383                 * @return {@code this} builder, for command chaining
1384                 */
1385                public Builder<G, C> individualCreationRetries(final int retries) {
1386                        if (retries < 0) {
1387                                throw new IllegalArgumentException(format(
1388                                        "Retry count must not be negative: %d",
1389                                        retries
1390                                ));
1391                        }
1392                        _individualCreationRetries = retries;
1393                        return this;
1394                }
1395
1396                /**
1397                 * The result mapper, which allows to change the evolution result after
1398                 * each generation.
1399                 *
1400                 * @since 4.0
1401                 * @see EvolutionResult#toUniquePopulation()
1402                 *
1403                 * @param mapper the evolution result mapper
1404                 * @return {@code this} builder, for command chaining
1405                 * @throws NullPointerException if the given {@code resultMapper} is
1406                 *         {@code null}
1407                 */
1408                public Builder<G, C> mapping(
1409                        final Function<
1410                                ? super EvolutionResult<G, C>,
1411                                EvolutionResult<G, C>
1412                        > mapper
1413                ) {
1414                        _mapper = requireNonNull(mapper::apply);
1415                        return this;
1416                }
1417
1418                /**
1419                 * Builds an new {@code Engine} instance from the set properties.
1420                 *
1421                 * @return an new {@code Engine} instance from the set properties
1422                 */
1423                public Engine<G, C> build() {
1424                        return new Engine<>(
1425                                _fitnessFunction,
1426                                _genotypeFactory,
1427                                _fitnessScaler,
1428                                _survivorsSelector,
1429                                _offspringSelector,
1430                                _alterer,
1431                                _validator,
1432                                _optimize,
1433                                getOffspringCount(),
1434                                getSurvivorsCount(),
1435                                _maximalPhenotypeAge,
1436                                _executor,
1437                                _evaluator != null
1438                                        ? _evaluator
1439                                        : new ConcurrentEvaluator<>(_executor),
1440                                _clock,
1441                                _individualCreationRetries,
1442                                _mapper
1443                        );
1444                }
1445
1446                private int getSurvivorsCount() {
1447                        return _populationSize - getOffspringCount();
1448                }
1449
1450                private int getOffspringCount() {
1451                        return (int)round(_offspringFraction*_populationSize);
1452                }
1453
1454                /**
1455                 * Return the used {@link Alterer} of the GA.
1456                 *
1457                 * @return the used {@link Alterer} of the GA.
1458                 */
1459                public Alterer<G, C> getAlterers() {
1460                        return _alterer;
1461                }
1462
1463                /**
1464                 * Return the {@link Clock} the engine is using for measuring the execution
1465                 * time.
1466                 *
1467                 * @since 3.1
1468                 *
1469                 * @return the clock used for measuring the execution time
1470                 */
1471                public Clock getClock() {
1472                        return _clock;
1473                }
1474
1475                /**
1476                 * Return the {@link Executor} the engine is using for executing the
1477                 * evolution steps.
1478                 *
1479                 * @since 3.1
1480                 *
1481                 * @return the executor used for performing the evolution steps
1482                 */
1483                public Executor getExecutor() {
1484                        return _executor;
1485                }
1486
1487                /**
1488                 * Return the fitness function of the GA engine.
1489                 *
1490                 * @since 3.1
1491                 *
1492                 * @return the fitness function
1493                 */
1494                public Function<? super Genotype<G>, ? extends C> getFitnessFunction() {
1495                        return _fitnessFunction;
1496                }
1497
1498                /**
1499                 * Return the fitness scaler of the GA engine.
1500                 *
1501                 * @since 3.1
1502                 *
1503                 * @return the fitness scaler
1504                 *
1505                 * @deprecated The fitness scaler will be remove in a future version.
1506                 */
1507                @Deprecated
1508                public Function<? super C, ? extends C> getFitnessScaler() {
1509                        return _fitnessScaler;
1510                }
1511
1512                /**
1513                 * Return the used genotype {@link Factory} of the GA. The genotype factory
1514                 * is used for creating the initial population and new, random individuals
1515                 * when needed (as replacement for invalid and/or died genotypes).
1516                 *
1517                 * @since 3.1
1518                 *
1519                 * @return the used genotype {@link Factory} of the GA.
1520                 */
1521                public Factory<Genotype<G>> getGenotypeFactory() {
1522                        return _genotypeFactory;
1523                }
1524
1525                /**
1526                 * Return the maximal allowed phenotype age.
1527                 *
1528                 * @since 3.1
1529                 *
1530                 * @return the maximal allowed phenotype age
1531                 */
1532                public long getMaximalPhenotypeAge() {
1533                        return _maximalPhenotypeAge;
1534                }
1535
1536                /**
1537                 * Return the offspring fraction.
1538                 *
1539                 * @return the offspring fraction.
1540                 */
1541                public double getOffspringFraction() {
1542                        return _offspringFraction;
1543                }
1544
1545                /**
1546                 * Return the used offspring {@link Selector} of the GA.
1547                 *
1548                 * @since 3.1
1549                 *
1550                 * @return the used offspring {@link Selector} of the GA.
1551                 */
1552                public Selector<G, C> getOffspringSelector() {
1553                        return _offspringSelector;
1554                }
1555
1556                /**
1557                 * Return the used survivor {@link Selector} of the GA.
1558                 *
1559                 * @since 3.1
1560                 *
1561                 * @return the used survivor {@link Selector} of the GA.
1562                 */
1563                public Selector<G, C> getSurvivorsSelector() {
1564                        return _survivorsSelector;
1565                }
1566
1567                /**
1568                 * Return the optimization strategy.
1569                 *
1570                 * @since 3.1
1571                 *
1572                 * @return the optimization strategy
1573                 */
1574                public Optimize getOptimize() {
1575                        return _optimize;
1576                }
1577
1578                /**
1579                 * Return the number of individuals of a population.
1580                 *
1581                 * @since 3.1
1582                 *
1583                 * @return the number of individuals of a population
1584                 */
1585                public int getPopulationSize() {
1586                        return _populationSize;
1587                }
1588
1589                /**
1590                 * Return the maximal number of attempt before the {@code Engine} gives
1591                 * up creating a valid individual ({@code Phenotype}).
1592                 *
1593                 * @since 3.1
1594                 *
1595                 * @return the maximal number of {@code Phenotype} creation attempts
1596                 */
1597                public int getIndividualCreationRetries() {
1598                        return _individualCreationRetries;
1599                }
1600
1601                /**
1602                 * Return the evolution result mapper.
1603                 *
1604                 * @since 4.0
1605                 *
1606                 * @return the evolution result mapper
1607                 */
1608                public UnaryOperator<EvolutionResult<G, C>> getMapper() {
1609                        return _mapper;
1610                }
1611
1612                /**
1613                 * Create a new builder, with the current configuration.
1614                 *
1615                 * @since 3.1
1616                 *
1617                 * @return a new builder, with the current configuration
1618                 */
1619                @Override
1620                public Builder<G, C> copy() {
1621                        return new Builder<G, C>(_genotypeFactory, _fitnessFunction)
1622                                .alterers(_alterer)
1623                                .clock(_clock)
1624                                .executor(_executor)
1625                                .evaluator(_evaluator)
1626                                .fitnessScaler(_fitnessScaler)
1627                                .maximalPhenotypeAge(_maximalPhenotypeAge)
1628                                .offspringFraction(_offspringFraction)
1629                                .offspringSelector(_offspringSelector)
1630                                .phenotypeValidator(_validator)
1631                                .optimize(_optimize)
1632                                .populationSize(_populationSize)
1633                                .survivorsSelector(_survivorsSelector)
1634                                .individualCreationRetries(_individualCreationRetries)
1635                                .mapping(_mapper);
1636                }
1637
1638        }
1639
1640}