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