Engine.java
0001 /*
0002  * Java Genetic Algorithm Library (jenetics-5.2.0).
0003  * Copyright (c) 2007-2020 Franz Wilhelmstötter
0004  *
0005  * Licensed under the Apache License, Version 2.0 (the "License");
0006  * you may not use this file except in compliance with the License.
0007  * You may obtain a copy of the License at
0008  *
0009  *      http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  *
0017  * Author:
0018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
0019  */
0020 package io.jenetics.engine;
0021 
0022 import static java.lang.String.format;
0023 import static java.util.Objects.requireNonNull;
0024 import static java.util.concurrent.CompletableFuture.supplyAsync;
0025 import static java.util.concurrent.ForkJoinPool.commonPool;
0026 
0027 import java.time.Clock;
0028 import java.util.concurrent.CompletableFuture;
0029 import java.util.concurrent.Executor;
0030 import java.util.function.Function;
0031 import java.util.function.Supplier;
0032 import java.util.function.UnaryOperator;
0033 import java.util.stream.Stream;
0034 
0035 import io.jenetics.Alterer;
0036 import io.jenetics.AltererResult;
0037 import io.jenetics.Chromosome;
0038 import io.jenetics.Gene;
0039 import io.jenetics.Genotype;
0040 import io.jenetics.Optimize;
0041 import io.jenetics.Phenotype;
0042 import io.jenetics.Selector;
0043 import io.jenetics.util.Copyable;
0044 import io.jenetics.util.Factory;
0045 import io.jenetics.util.ISeq;
0046 import io.jenetics.util.MSeq;
0047 import io.jenetics.util.NanoClock;
0048 import io.jenetics.util.Seq;
0049 
0050 /**
0051  * Genetic algorithm <em>engine</em> which is the main class. The following
0052  * example shows the main steps in initializing and executing the GA.
0053  *
0054  <pre>{@code
0055  * public class RealFunction {
0056  *    // Definition of the fitness function.
0057  *    private static Double eval(final Genotype<DoubleGene> gt) {
0058  *        final double x = gt.gene().doubleValue();
0059  *        return cos(0.5 + sin(x))*cos(x);
0060  *    }
0061  *
0062  *    public static void main(String[] args) {
0063  *        // Create/configuring the engine via its builder.
0064  *        final Engine<DoubleGene, Double> engine = Engine
0065  *            .builder(
0066  *                RealFunction::eval,
0067  *                DoubleChromosome.of(0.0, 2.0*PI))
0068  *            .populationSize(500)
0069  *            .optimize(Optimize.MINIMUM)
0070  *            .alterers(
0071  *                new Mutator<>(0.03),
0072  *                new MeanAlterer<>(0.6))
0073  *            .build();
0074  *
0075  *        // Execute the GA (engine).
0076  *        final Phenotype<DoubleGene, Double> result = engine.stream()
0077  *             // Truncate the evolution stream if no better individual could
0078  *             // be found after 5 consecutive generations.
0079  *            .limit(bySteadyFitness(5))
0080  *             // Terminate the evolution after maximal 100 generations.
0081  *            .limit(100)
0082  *            .collect(toBestPhenotype());
0083  *     }
0084  * }
0085  * }</pre>
0086  *
0087  * The architecture allows to decouple the configuration of the engine from the
0088  * execution. The {@code Engine} is configured via the {@code Engine.Builder}
0089  * class and can't be changed after creation. The actual <i>evolution</i> is
0090  * performed by the {@link EvolutionStream}, which is created by the
0091  * {@code Engine}.
0092  *
0093  * @implNote
0094  *     This class is thread safe:
0095  *     No mutable state is maintained by the engine. Therefore it is save to
0096  *     create multiple evolution streams with one engine, which may be actually
0097  *     used in different threads.
0098  *
0099  @see Engine.Builder
0100  @see EvolutionStart
0101  @see EvolutionResult
0102  @see EvolutionStream
0103  @see EvolutionStatistics
0104  @see Codec
0105  @see Constraint
0106  *
0107  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0108  @since 3.0
0109  @version 5.2
0110  */
0111 public final class Engine<
0112     extends Gene<?, G>,
0113     extends Comparable<? super C>
0114 >
0115     implements
0116         Evolution<G, C>,
0117         Function<EvolutionStart<G, C>, EvolutionResult<G, C>>,
0118         EvolutionStreamable<G, C>
0119 {
0120 
0121     // Problem definition.
0122     private final Evaluator<G, C> _evaluator;
0123     private final Factory<Genotype<G>> _genotypeFactory;
0124     private final Constraint<G, C> _constraint;
0125     private final Optimize _optimize;
0126 
0127     // Evolution parameters.
0128     private final EvolutionParams<G, C> _evolutionParams;
0129 
0130     // Execution context for concurrent execution of evolving steps.
0131     private final Executor _executor;
0132     private final Clock _clock;
0133     private final UnaryOperator<EvolutionResult<G, C>> _mapper;
0134 
0135 
0136     /**
0137      * Create a new GA engine with the given parameters.
0138      *
0139      @param genotypeFactory the genotype factory this GA is working with.
0140      @param constraint phenotype constraint which can override the default
0141      *        implementation the {@link Phenotype#isValid()} method and repairs
0142      *        invalid phenotypes when needed.
0143      @param optimize the kind of optimization (minimize or maximize)
0144      @param executor the executor used for executing the single evolve steps
0145      @param evaluator the population fitness evaluator
0146      @param clock the clock used for calculating the timing results
0147      @throws NullPointerException if one of the arguments is {@code null}
0148      @throws IllegalArgumentException if the given integer values are smaller
0149      *         than one.
0150      */
0151     Engine(
0152         final Evaluator<G, C> evaluator,
0153         final Factory<Genotype<G>> genotypeFactory,
0154         final Constraint<G, C> constraint,
0155         final Optimize optimize,
0156         final EvolutionParams<G, C> evolutionParams,
0157         final Executor executor,
0158         final Clock clock,
0159         final UnaryOperator<EvolutionResult<G, C>> mapper
0160     ) {
0161         _evaluator = requireNonNull(evaluator);
0162         _genotypeFactory = requireNonNull(genotypeFactory);
0163         _constraint = requireNonNull(constraint);
0164         _optimize = requireNonNull(optimize);
0165         _evolutionParams = requireNonNull(evolutionParams);
0166         _executor = requireNonNull(executor);
0167         _clock = requireNonNull(clock);
0168         _mapper = requireNonNull(mapper);
0169     }
0170 
0171     /**
0172      * This method is an <i>alias</i> for the {@link #evolve(EvolutionStart)}
0173      * method.
0174      *
0175      @since 3.1
0176      *
0177      @see Evolution
0178      *
0179      @deprecated Will be removed and superseded by {@link #evolve(EvolutionStart)}
0180      */
0181     @Deprecated
0182     @Override
0183     public EvolutionResult<G, C> apply(final EvolutionStart<G, C> start) {
0184         return evolve(start);
0185     }
0186 
0187     @Override
0188     public EvolutionResult<G, C> evolve(final EvolutionStart<G, C> start) {
0189         // Create initial population if `start` is empty.
0190         final EvolutionStart<G, C> es = start.population().isEmpty()
0191             ? evolutionStart(start)
0192             : start;
0193 
0194         final EvolutionTiming timing = new EvolutionTiming(_clock);
0195         timing.evolve.start();
0196 
0197         // Initial evaluation of the population.
0198         final ISeq<Phenotype<G, C>> evaluated = timing.evaluation.timing(() ->
0199             evaluate(es.population())
0200         );
0201 
0202         // Select the offspring population.
0203         final CompletableFuture<ISeq<Phenotype<G, C>>> offspring =
0204             supplyAsync(() ->
0205                 timing.offspringSelection.timing(() ->
0206                     selectOffspring(evaluated)
0207                 ),
0208                 _executor
0209             );
0210 
0211         // Select the survivor population.
0212         final CompletableFuture<ISeq<Phenotype<G, C>>> survivors =
0213             supplyAsync(() ->
0214                 timing.survivorsSelection.timing(() ->
0215                     selectSurvivors(evaluated)
0216                 ),
0217                 _executor
0218             );
0219 
0220         // Altering the offspring population.
0221         final CompletableFuture<AltererResult<G, C>> alteredOffspring =
0222             offspring.thenApplyAsync(off ->
0223                 timing.offspringAlter.timing(() ->
0224                     _evolutionParams.alterer().alter(off, es.generation())
0225                 ),
0226                 _executor
0227             );
0228 
0229         // Filter and replace invalid and old survivor individuals.
0230         final CompletableFuture<FilterResult<G, C>> filteredSurvivors =
0231             survivors.thenApplyAsync(sur ->
0232                 timing.survivorFilter.timing(() ->
0233                     filter(sur, es.generation())
0234                 ),
0235                 _executor
0236             );
0237 
0238         // Filter and replace invalid and old offspring individuals.
0239         final CompletableFuture<FilterResult<G, C>> filteredOffspring =
0240             alteredOffspring.thenApplyAsync(off ->
0241                 timing.offspringFilter.timing(() ->
0242                     filter(off.population(), es.generation())
0243                 ),
0244                 _executor
0245             );
0246 
0247         // Combining survivors and offspring to the new population.
0248         final CompletableFuture<ISeq<Phenotype<G, C>>> population =
0249             filteredSurvivors.thenCombineAsync(
0250                 filteredOffspring,
0251                 (s, o-> ISeq.of(s.population.append(o.population)),
0252                 _executor
0253             );
0254 
0255         // Evaluate the fitness-function and wait for result.
0256         final ISeq<Phenotype<G, C>> pop = population.join();
0257         final ISeq<Phenotype<G, C>> result = timing.evaluation.timing(() ->
0258             evaluate(pop)
0259         );
0260 
0261         final int killCount =
0262             filteredOffspring.join().killCount +
0263             filteredSurvivors.join().killCount;
0264 
0265         final int invalidCount =
0266             filteredOffspring.join().invalidCount +
0267             filteredSurvivors.join().invalidCount;
0268 
0269         final int alterationCount = alteredOffspring.join().alterations();
0270 
0271         EvolutionResult<G, C> er = EvolutionResult.of(
0272             _optimize,
0273             result,
0274             es.generation(),
0275             timing.toDurations(),
0276             killCount,
0277             invalidCount,
0278             alterationCount
0279         );
0280         if (!UnaryOperator.identity().equals(_mapper)) {
0281             final EvolutionResult<G, C> mapped = _mapper.apply(er);
0282             er = er.with(timing.evaluation.timing(() ->
0283                 evaluate(mapped.population())
0284             ));
0285         }
0286 
0287         timing.evolve.stop();
0288         return er.with(timing.toDurations());
0289     }
0290 
0291     // Selects the survivors population. A new population object is returned.
0292     private ISeq<Phenotype<G, C>>
0293     selectSurvivors(final ISeq<Phenotype<G, C>> population) {
0294         return _evolutionParams.survivorsSize() 0
0295             ? _evolutionParams.survivorsSelector()
0296                 .select(population, _evolutionParams.survivorsSize(), _optimize)
0297             : ISeq.empty();
0298     }
0299 
0300     // Selects the offspring population. A new population object is returned.
0301     private ISeq<Phenotype<G, C>>
0302     selectOffspring(final ISeq<Phenotype<G, C>> population) {
0303         return _evolutionParams.offspringSize() 0
0304             ? _evolutionParams.offspringSelector()
0305                 .select(population, _evolutionParams.offspringSize(), _optimize)
0306             : ISeq.empty();
0307     }
0308 
0309     // Filters out invalid and old individuals. Filtering is done in place.
0310     private FilterResult<G, C> filter(
0311         final Seq<Phenotype<G, C>> population,
0312         final long generation
0313     ) {
0314         int killCount = 0;
0315         int invalidCount = 0;
0316 
0317         final MSeq<Phenotype<G, C>> pop = MSeq.of(population);
0318         for (int i = 0, n = pop.size(); i < n; ++i) {
0319             final Phenotype<G, C> individual = pop.get(i);
0320 
0321             if (!_constraint.test(individual)) {
0322                 pop.set(i, _constraint.repair(individual, generation));
0323                 ++invalidCount;
0324             else if (individual.age(generation>
0325                         _evolutionParams.maximalPhenotypeAge())
0326             {
0327                 pop.set(i, Phenotype.of(_genotypeFactory.newInstance(), generation));
0328                 ++killCount;
0329             }
0330         }
0331 
0332         return new FilterResult<>(pop.toISeq(), killCount, invalidCount);
0333     }
0334 
0335 
0336     /* *************************************************************************
0337      * Evaluation methods.
0338      **************************************************************************/
0339 
0340     /**
0341      * Evaluates the fitness function of the given population with the configured
0342      {@link Evaluator} of this engine and returns a new population
0343      * with its fitness value assigned.
0344      *
0345      @since 5.0
0346      *
0347      @see Evaluator
0348      @see Evaluator#eval(Seq)
0349      *
0350      @param population the population to evaluate
0351      @return a new population with assigned fitness values
0352      @throws IllegalStateException if the configured fitness function doesn't
0353      *         return a population with the same size as the input population.
0354      *         This exception is also thrown if one of the populations
0355      *         phenotype has no fitness value assigned.
0356      */
0357     public ISeq<Phenotype<G, C>> evaluate(final Seq<Phenotype<G, C>> population) {
0358         final ISeq<Phenotype<G, C>> evaluated = _evaluator.eval(population);
0359 
0360         if (population.size() != evaluated.size()) {
0361             throw new IllegalStateException(format(
0362                 "Expected %d individuals, but got %d. " +
0363                     "Check your evaluator function.",
0364                 population.size(), evaluated.size()
0365             ));
0366         }
0367         if (!evaluated.forAll(Phenotype::isEvaluated)) {
0368             throw new IllegalStateException(
0369                 "Some phenotypes have no assigned fitness value. " +
0370                     "Check your evaluator function."
0371             );
0372         }
0373 
0374         return evaluated;
0375     }
0376 
0377 
0378     /* *************************************************************************
0379      * Evolution Stream creation.
0380      **************************************************************************/
0381 
0382     @Override
0383     public EvolutionStream<G, C>
0384     stream(final Supplier<EvolutionStart<G, C>> start) {
0385         return EvolutionStream.ofEvolution(
0386             () -> evolutionStart(start.get()),
0387             this
0388         );
0389     }
0390 
0391     @Override
0392     public EvolutionStream<G, C> stream(final EvolutionInit<G> init) {
0393         return stream(evolutionStart(init));
0394     }
0395 
0396     private EvolutionStart<G, C>
0397     evolutionStart(final EvolutionStart<G, C> start) {
0398         final ISeq<Phenotype<G, C>> population = start.population();
0399         final long gen = start.generation();
0400 
0401         final Stream<Phenotype<G, C>> stream = Stream.concat(
0402             population.stream(),
0403             _genotypeFactory.instances()
0404                 .map(gt -> Phenotype.of(gt, gen))
0405         );
0406 
0407         final ISeq<Phenotype<G, C>> pop = stream
0408             .limit(populationSize())
0409             .collect(ISeq.toISeq());
0410 
0411         return EvolutionStart.of(pop, gen);
0412     }
0413 
0414     private EvolutionStart<G, C>
0415     evolutionStart(final EvolutionInit<G> init) {
0416         final ISeq<Genotype<G>> pop = init.population();
0417         final long gen = init.generation();
0418 
0419         return evolutionStart(
0420             EvolutionStart.of(
0421                 pop.map(gt -> Phenotype.of(gt, gen)),
0422                 gen
0423             )
0424         );
0425     }
0426 
0427     /* *************************************************************************
0428      * Property access methods.
0429      **************************************************************************/
0430 
0431     /**
0432      * Return the used genotype {@link Factory} of the GA. The genotype factory
0433      * is used for creating the initial population and new, random individuals
0434      * when needed (as replacement for invalid and/or died genotypes).
0435      *
0436      @return the used genotype {@link Factory} of the GA.
0437      */
0438     public Factory<Genotype<G>> genotypeFactory() {
0439         return _genotypeFactory;
0440     }
0441 
0442     /**
0443      * Return the used genotype {@link Factory} of the GA. The genotype factory
0444      * is used for creating the initial population and new, random individuals
0445      * when needed (as replacement for invalid and/or died genotypes).
0446      *
0447      @return the used genotype {@link Factory} of the GA.
0448      @deprecated Use {@link #genotypeFactory()} instead
0449      */
0450     @Deprecated
0451     public Factory<Genotype<G>> getGenotypeFactory() {
0452         return _genotypeFactory;
0453     }
0454 
0455     /**
0456      * Return the constraint of the evolution problem.
0457      *
0458      @since 5.0
0459      *
0460      @return the constraint of the evolution problem
0461      */
0462     public Constraint<G, C> constraint() {
0463         return _constraint;
0464     }
0465 
0466     /**
0467      * Return the constraint of the evolution problem.
0468      *
0469      @since 5.0
0470      *
0471      @return the constraint of the evolution problem
0472      @deprecated Use {@link #constraint()} instead
0473      */
0474     @Deprecated
0475     public Constraint<G, C> getConstraint() {
0476         return _constraint;
0477     }
0478 
0479     /**
0480      * Return the used survivor {@link Selector} of the GA.
0481      *
0482      @return the used survivor {@link Selector} of the GA.
0483      */
0484     public Selector<G, C> survivorsSelector() {
0485         return _evolutionParams.survivorsSelector();
0486     }
0487 
0488     /**
0489      * Return the used survivor {@link Selector} of the GA.
0490      *
0491      @return the used survivor {@link Selector} of the GA.
0492      @deprecated Use {@link #survivorsSelector()} instead
0493      */
0494     @Deprecated
0495     public Selector<G, C> getSurvivorsSelector() {
0496         return _evolutionParams.survivorsSelector();
0497     }
0498 
0499     /**
0500      * Return the used offspring {@link Selector} of the GA.
0501      *
0502      @return the used offspring {@link Selector} of the GA.
0503      */
0504     public Selector<G, C> offspringSelector() {
0505         return _evolutionParams.offspringSelector();
0506     }
0507 
0508     /**
0509      * Return the used offspring {@link Selector} of the GA.
0510      *
0511      @return the used offspring {@link Selector} of the GA.
0512      @deprecated Use {@link #offspringSelector()} instead
0513      */
0514     @Deprecated
0515     public Selector<G, C> getOffspringSelector() {
0516         return _evolutionParams.offspringSelector();
0517     }
0518 
0519     /**
0520      * Return the used {@link Alterer} of the GA.
0521      *
0522      @return the used {@link Alterer} of the GA.
0523      */
0524     public Alterer<G, C> alterer() {
0525         return _evolutionParams.alterer();
0526     }
0527 
0528     /**
0529      * Return the used {@link Alterer} of the GA.
0530      *
0531      @return the used {@link Alterer} of the GA.
0532      @deprecated Use {@link #alterer()} instead
0533      */
0534     @Deprecated
0535     public Alterer<G, C> getAlterer() {
0536         return _evolutionParams.alterer();
0537     }
0538 
0539     /**
0540      * Return the number of selected offspring.
0541      *
0542      @return the number of selected offspring
0543      */
0544     public int offspringSize() {
0545         return _evolutionParams.offspringSize();
0546     }
0547 
0548     /**
0549      * Return the number of selected offspring.
0550      *
0551      @return the number of selected offspring
0552      @deprecated Use {@link #offspringSize()} instead
0553      */
0554     @Deprecated
0555     public int getOffspringCount() {
0556         return _evolutionParams.offspringSize();
0557     }
0558 
0559     /**
0560      * The number of selected survivors.
0561      *
0562      @return the number of selected survivors
0563      */
0564     public int survivorsSize() {
0565         return _evolutionParams.survivorsSize();
0566     }
0567 
0568     /**
0569      * The number of selected survivors.
0570      *
0571      @return the number of selected survivors
0572      @deprecated Use {@link #survivorsSize()} instead
0573      */
0574     @Deprecated
0575     public int getSurvivorsCount() {
0576         return _evolutionParams.survivorsSize();
0577     }
0578 
0579     /**
0580      * Return the number of individuals of a population.
0581      *
0582      @return the number of individuals of a population
0583      */
0584     public int populationSize() {
0585         return _evolutionParams.populationSize();
0586     }
0587 
0588     /**
0589      * Return the number of individuals of a population.
0590      *
0591      @return the number of individuals of a population
0592      @deprecated Use {@link #populationSize()} instead
0593      */
0594     @Deprecated
0595     public int getPopulationSize() {
0596         return _evolutionParams.populationSize();
0597     }
0598 
0599     /**
0600      * Return the maximal allowed phenotype age.
0601      *
0602      @return the maximal allowed phenotype age
0603      */
0604     public long maximalPhenotypeAge() {
0605         return _evolutionParams.maximalPhenotypeAge();
0606     }
0607 
0608     /**
0609      * Return the maximal allowed phenotype age.
0610      *
0611      @return the maximal allowed phenotype age
0612      @deprecated Use {@link #maximalPhenotypeAge()} instead
0613      */
0614     @Deprecated
0615     public long getMaximalPhenotypeAge() {
0616         return _evolutionParams.maximalPhenotypeAge();
0617     }
0618 
0619     /**
0620      * Return the optimization strategy.
0621      *
0622      @return the optimization strategy
0623      */
0624     public Optimize optimize() {
0625         return _optimize;
0626     }
0627 
0628     /**
0629      * Return the optimization strategy.
0630      *
0631      @return the optimization strategy
0632      @deprecated Use {@link #optimize()} instead
0633      */
0634     @Deprecated
0635     public Optimize getOptimize() {
0636         return _optimize;
0637     }
0638 
0639     /**
0640      * Return the {@link Clock} the engine is using for measuring the execution
0641      * time.
0642      *
0643      @return the clock used for measuring the execution time
0644      */
0645     public Clock clock() {
0646         return _clock;
0647     }
0648 
0649     /**
0650      * Return the {@link Clock} the engine is using for measuring the execution
0651      * time.
0652      *
0653      @return the clock used for measuring the execution time
0654      @deprecated Use {@link #clock()} instead
0655      */
0656     @Deprecated
0657     public Clock getClock() {
0658         return _clock;
0659     }
0660 
0661     /**
0662      * Return the {@link Executor} the engine is using for executing the
0663      * evolution steps.
0664      *
0665      @return the executor used for performing the evolution steps
0666      */
0667     public Executor executor() {
0668         return _executor;
0669     }
0670 
0671     /**
0672      * Return the {@link Executor} the engine is using for executing the
0673      * evolution steps.
0674      *
0675      @return the executor used for performing the evolution steps
0676      @deprecated Use {@link #executor()} instead
0677      */
0678     @Deprecated
0679     public Executor getExecutor() {
0680         return _executor;
0681     }
0682 
0683     /**
0684      * Return the evolution result mapper.
0685      *
0686      @since 4.0
0687      *
0688      @return the evolution result mapper
0689      */
0690     public UnaryOperator<EvolutionResult<G, C>> mapper() {
0691         return _mapper;
0692     }
0693 
0694     /**
0695      * Return the evolution result mapper.
0696      *
0697      @since 4.0
0698      *
0699      @return the evolution result mapper
0700      @deprecated Use {@link #mapper()} instead
0701      */
0702     @Deprecated
0703     public UnaryOperator<EvolutionResult<G, C>> getMapper() {
0704         return _mapper;
0705     }
0706 
0707     /**
0708      * Create a new evolution {@code Engine.Builder} initialized with the values
0709      * of the current evolution {@code Engine}. With this method, the evolution
0710      * engine can serve as a template for a new one.
0711      *
0712      @return a new engine builder
0713      */
0714     public Builder<G, C> toBuilder() {
0715         return new Builder<>(_evaluator, _genotypeFactory)
0716             .clock(_clock)
0717             .executor(_executor)
0718             .optimize(_optimize)
0719             .constraint(_constraint)
0720             .evolutionParams(_evolutionParams)
0721             .mapping(_mapper);
0722     }
0723 
0724     /**
0725      * Create a new evolution {@code Engine.Builder} initialized with the values
0726      * of the current evolution {@code Engine}. With this method, the evolution
0727      * engine can serve as a template for a new one.
0728      *
0729      @return a new engine builder
0730      @deprecated Use {@link #toBuilder()} instead
0731      */
0732     @Deprecated
0733     public Builder<G, C> builder() {
0734         return toBuilder();
0735     }
0736 
0737 
0738     /* *************************************************************************
0739      * Static Builder methods.
0740      **************************************************************************/
0741 
0742     /**
0743      * Create a new evolution {@code Engine.Builder} with the given fitness
0744      * function and genotype factory.
0745      *
0746      @param ff the fitness function
0747      @param gtf the genotype factory
0748      @param <G> the gene type
0749      @param <C> the fitness function result type
0750      @return a new engine builder
0751      @throws java.lang.NullPointerException if one of the arguments is
0752      *         {@code null}.
0753      */
0754     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0755     Builder<G, C> builder(
0756         final Function<? super Genotype<G>, ? extends C> ff,
0757         final Factory<Genotype<G>> gtf
0758     ) {
0759         return new Builder<>(Evaluators.concurrent(ff, commonPool()), gtf);
0760     }
0761 
0762     /**
0763      * Create a new evolution {@code Engine.Builder} with the given fitness
0764      * function and problem {@code codec}.
0765      *
0766      @since 3.2
0767      *
0768      @param ff the fitness evaluator
0769      @param codec the problem codec
0770      @param <T> the fitness function input type
0771      @param <C> the fitness function result type
0772      @param <G> the gene type
0773      @return a new engine builder
0774      @throws java.lang.NullPointerException if one of the arguments is
0775      *         {@code null}.
0776      */
0777     public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
0778     Builder<G, C> builder(
0779         final Function<? super T, ? extends C> ff,
0780         final Codec<T, G> codec
0781     ) {
0782         return builder(ff.compose(codec.decoder()), codec.encoding());
0783     }
0784 
0785     /**
0786      * Create a new evolution {@code Engine.Builder} for the given
0787      {@link Problem}.
0788      *
0789      @since 3.4
0790      *
0791      @param problem the problem to be solved by the evolution {@code Engine}
0792      @param <T> the (<i>native</i>) argument type of the problem fitness function
0793      @param <G> the gene type the evolution engine is working with
0794      @param <C> the result type of the fitness function
0795      @return Create a new evolution {@code Engine.Builder}
0796      */
0797     public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
0798     Builder<G, C> builder(final Problem<T, G, C> problem) {
0799         return builder(problem.fitness(), problem.codec());
0800     }
0801 
0802     /**
0803      * Create a new evolution {@code Engine.Builder} with the given fitness
0804      * function and chromosome templates.
0805      *
0806      @param ff the fitness function
0807      @param chromosome the first chromosome
0808      @param chromosomes the chromosome templates
0809      @param <G> the gene type
0810      @param <C> the fitness function result type
0811      @return a new engine builder
0812      @throws java.lang.NullPointerException if one of the arguments is
0813      *         {@code null}.
0814      */
0815     @SafeVarargs
0816     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
0817     Builder<G, C> builder(
0818         final Function<? super Genotype<G>, ? extends C> ff,
0819         final Chromosome<G> chromosome,
0820         final Chromosome<G>... chromosomes
0821     ) {
0822         return builder(ff, Genotype.of(chromosome, chromosomes));
0823     }
0824 
0825 
0826     /* *************************************************************************
0827      * Engine builder
0828      **************************************************************************/
0829 
0830 
0831     /**
0832      * Builder class for building GA {@code Engine} instances.
0833      *
0834      @see Engine
0835      *
0836      @param <G> the gene type
0837      @param <C> the fitness function result type
0838      *
0839      @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0840      @since 3.0
0841      @version 5.2
0842      */
0843     public static final class Builder<
0844         extends Gene<?, G>,
0845         extends Comparable<? super C>
0846     >
0847         implements Copyable<Builder<G, C>>
0848     {
0849 
0850         // No default values for this properties.
0851         private final Evaluator<G, C> _evaluator;
0852         private final Factory<Genotype<G>> _genotypeFactory;
0853         private Constraint<G, C> _constraint;
0854         private Optimize _optimize = Optimize.MAXIMUM;
0855 
0856         // Evolution parameters.
0857         private final EvolutionParams.Builder<G, C> _evolutionParams =
0858             EvolutionParams.builder();
0859 
0860 
0861         // Engine execution environment.
0862         private Executor _executor = commonPool();
0863         private Clock _clock = NanoClock.systemUTC();
0864 
0865         private UnaryOperator<EvolutionResult<G, C>> _mapper = UnaryOperator.identity();
0866 
0867         /**
0868          * Create a new evolution {@code Engine.Builder} with the given fitness
0869          * evaluator and genotype factory. This is the most general way for
0870          * creating an engine builder.
0871          *
0872          @since 5.0
0873          *
0874          @see Engine#builder(Function, Codec)
0875          @see Engine#builder(Function, Factory)
0876          @see Engine#builder(Problem)
0877          @see Engine#builder(Function, Chromosome, Chromosome[])
0878          *
0879          @param evaluator the fitness evaluator
0880          @param genotypeFactory the genotype factory
0881          @throws NullPointerException if one of the arguments is {@code null}.
0882          */
0883         public Builder(
0884             final Evaluator<G, C> evaluator,
0885             final Factory<Genotype<G>> genotypeFactory
0886         ) {
0887             _genotypeFactory = requireNonNull(genotypeFactory);
0888             _evaluator = requireNonNull(evaluator);
0889         }
0890 
0891         /**
0892          * Set the evolution parameters used by the engine.
0893          *
0894          @since 5.2
0895          *
0896          @param params the evolution parameter
0897          @return {@code this} builder, for command chaining
0898          @throws NullPointerException if the {@code params} is {@code null}.
0899          */
0900         public Builder<G, C> evolutionParams(final EvolutionParams<G, C> params) {
0901             _evolutionParams.evolutionParams(params);
0902             return this;
0903         }
0904 
0905         /**
0906          * The selector used for selecting the offspring population. <i>Default
0907          * values is set to {@code TournamentSelector<>(3)}.</i>
0908          *
0909          @param selector used for selecting the offspring population
0910          @return {@code this} builder, for command chaining
0911          @throws NullPointerException if one of the {@code selector} is
0912          *         {@code null}.
0913          */
0914         public Builder<G, C> offspringSelector(final Selector<G, C> selector) {
0915             _evolutionParams.offspringSelector(selector);
0916             return this;
0917         }
0918 
0919         /**
0920          * The selector used for selecting the survivors population. <i>Default
0921          * values is set to {@code TournamentSelector<>(3)}.</i>
0922          *
0923          @param selector used for selecting survivors population
0924          @return {@code this} builder, for command chaining
0925          @throws NullPointerException if one of the {@code selector} is
0926          *         {@code null}.
0927          */
0928         public Builder<G, C> survivorsSelector(final Selector<G, C> selector) {
0929             _evolutionParams.survivorsSelector(selector);
0930             return this;
0931         }
0932 
0933         /**
0934          * The selector used for selecting the survivors and offspring
0935          * population. <i>Default values is set to
0936          * {@code TournamentSelector<>(3)}.</i>
0937          *
0938          @param selector used for selecting survivors and offspring population
0939          @return {@code this} builder, for command chaining
0940          @throws NullPointerException if one of the {@code selector} is
0941          *         {@code null}.
0942          */
0943         public Builder<G, C> selector(final Selector<G, C> selector) {
0944             _evolutionParams.selector(selector);
0945             return this;
0946         }
0947 
0948         /**
0949          * The alterers used for alter the offspring population. <i>Default
0950          * values is set to {@code new SinglePointCrossover<>(0.2)} followed by
0951          * {@code new Mutator<>(0.15)}.</i>
0952          *
0953          @param first the first alterer used for alter the offspring
0954          *        population
0955          @param rest the rest of the alterers used for alter the offspring
0956          *        population
0957          @return {@code this} builder, for command chaining
0958          @throws NullPointerException if one of the alterers is {@code null}.
0959          */
0960         @SafeVarargs
0961         public final Builder<G, C> alterers(
0962             final Alterer<G, C> first,
0963             final Alterer<G, C>... rest
0964         ) {
0965             _evolutionParams.alterers(first, rest);
0966             return this;
0967         }
0968 
0969         /**
0970          * The phenotype constraint is used for detecting invalid individuals
0971          * and repairing them.
0972          *
0973          <p><i>Default implementation uses {@code Phenotype::isValid} for
0974          * validating the phenotype.</i></p>
0975          *
0976          @since 5.0
0977          *
0978          @param constraint phenotype constraint which can override the default
0979          *        implementation the {@link Phenotype#isValid()} method and repairs
0980          *        invalid phenotypes when needed.
0981          @return {@code this} builder, for command chaining
0982          @throws NullPointerException if one of the {@code constraint} is
0983          *         {@code null}.
0984          */
0985         public Builder<G, C> constraint(final Constraint<G, C> constraint) {
0986             _constraint = constraint;
0987             return this;
0988         }
0989 
0990         /**
0991          * The optimization strategy used by the engine. <i>Default values is
0992          * set to {@code Optimize.MAXIMUM}.</i>
0993          *
0994          @param optimize the optimization strategy used by the engine
0995          @return {@code this} builder, for command chaining
0996          @throws NullPointerException if one of the {@code optimize} is
0997          *         {@code null}.
0998          */
0999         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(- 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