001/* 002 * Java Genetic Algorithm Library (jenetics-8.1.0). 003 * Copyright (c) 2007-2024 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.ext; 021 022import static java.lang.String.format; 023 024import io.jenetics.Gene; 025import io.jenetics.Mutator; 026import io.jenetics.TruncationSelector; 027import io.jenetics.engine.Engine.Builder; 028import io.jenetics.engine.Engine.Setup; 029import io.jenetics.internal.util.Requires; 030 031/** 032 * Setup for a (μ + λ)-Evolution Strategy. Applying this setup is done in the 033 * following way. 034 * {@snippet lang="java": 035 * final var engine = Engine.builder(problem) 036 * .setup(new MpLEvolutionStrategy<>(μ, λ, p)) 037 * .build(); 038 * } 039 * 040 * And is equivalent to the following builder setup. 041 * {@snippet lang="java": 042 * final var engine = Engine.builder(problem) 043 * .populationSize(λ) 044 * .survivorsSize(μ) 045 * .offspringSelector(new TruncationSelector<>(μ)) 046 * .alterers(new Mutator<>(p)) 047 * .build(); 048 * } 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 */ 057public final class MpLEvolutionStrategy< 058 G extends Gene<?, G>, 059 C 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 the 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 MpLEvolutionStrategy( 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 the 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 MpLEvolutionStrategy(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(_mu) 116 .selector(new TruncationSelector<>(_mu)) 117 .alterers(new Mutator<>(_mutationProbability)); 118 } 119 120}