MLEvolutionStrategy.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-6.3.0).
003  * Copyright (c) 2007-2021 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  */
020 package io.jenetics.ext;
021 
022 import static java.lang.String.format;
023 
024 import io.jenetics.Gene;
025 import io.jenetics.Mutator;
026 import io.jenetics.TruncationSelector;
027 import io.jenetics.engine.Engine.Builder;
028 import io.jenetics.engine.Engine.Setup;
029 import io.jenetics.internal.util.Requires;
030 
031 /**
032  * Setup for a (μ, λ)-Evolution Strategy. Applying this setup is done in the
033  * following way.
034  <pre>{@code
035  * final var engine = Engine.builder(problem)
036  *     .setup(new MLEvolutionStrategy<>(μ, λ, p)
037  *     .build();
038  * }</pre>
039  *
040  * And is equivalent to the following builder setup.
041  <pre>{@code
042  * final var engine = Engine.builder(problem)
043  *     .populationSize(λ)
044  *     .survivorsSize(0)
045  *     .offspringSelector(new TruncationSelector<>(μ))
046  *     .alterers(new Mutator<>(p))
047  *     .build();
048  * }</pre>
049  *
050  @param <G> the gene type
051  @param <C> the fitness result type
052  *
053  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
054  @version 6.0
055  @since 6.0
056  */
057 public final class MLEvolutionStrategy<
058     extends Gene<?, G>,
059     extends Comparable<? super C>
060 >
061     implements Setup<G, C>
062 {
063 
064     private final int _mu;
065     private final int _lambda;
066     private final double _mutationProbability;
067 
068     /**
069      * Create a new (μ, λ)-Evolution Strategy with the given parameters.
070      *
071      @param mu the number of fittest individuals to be selected
072      @param lambda the population count
073      @param mutationProbability the mutation probability
074      @throws IllegalArgumentException if {@code mu < 2} or {@code lambda < mu}
075      *         or {@code mutationProbability not in [0, 1]}
076      */
077     public MLEvolutionStrategy(
078         final int mu,
079         final int lambda,
080         final double mutationProbability
081     ) {
082         if (mu < 2) {
083             throw new IllegalArgumentException(format(
084                 "mu (μ) must be greater or equal 2: %d.", mu
085             ));
086         }
087         if (lambda < mu) {
088             throw new IllegalArgumentException(format(
089                 "lambda (λ) must be greater or equal then μ [μ=%d, λ=%d].",
090                 mu, lambda
091             ));
092         }
093 
094         _mu = mu;
095         _lambda = lambda;
096         _mutationProbability = Requires.probability(mutationProbability);
097     }
098 
099     /**
100      * Create a new (μ, λ)-Evolution Strategy with the given parameters. The
101      * mutation probability is set to {@link Mutator#DEFAULT_ALTER_PROBABILITY}.
102      *
103      @param mu the number of fittest individuals to be selected
104      @param lambda the population count
105      @throws IllegalArgumentException if {@code mu < 2} or {@code lambda < mu}
106      *         or {@code mutationProbability not in [0, 1]}
107      */
108     public MLEvolutionStrategy(final int mu, final int lambda) {
109         this(mu, lambda, Mutator.DEFAULT_ALTER_PROBABILITY);
110     }
111 
112     @Override
113     public void apply(final Builder<G, C> builder) {
114         builder.populationSize(_lambda)
115             .survivorsSize(0)
116             .offspringSelector(new TruncationSelector<>(_mu))
117             .alterers(new Mutator<>(_mutationProbability));
118     }
119 
120 }