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