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