/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math3.genetics;

import org.apache.commons.math3.exception.OutOfRangeException;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.random.JDKRandomGenerator;

Implementation of a genetic algorithm. All factors that govern the operation of the algorithm can be configured for a specific problem.
Since:2.0
/** * Implementation of a genetic algorithm. All factors that govern the operation * of the algorithm can be configured for a specific problem. * * @since 2.0 */
public class GeneticAlgorithm {
Static random number generator shared by GA implementation classes. Set the randomGenerator seed to get reproducible results. Use setRandomGenerator(RandomGenerator) to supply an alternative to the default JDK-provided PRNG.
/** * Static random number generator shared by GA implementation classes. Set the randomGenerator seed to get * reproducible results. Use {@link #setRandomGenerator(RandomGenerator)} to supply an alternative to the default * JDK-provided PRNG. */
//@GuardedBy("this") private static RandomGenerator randomGenerator = new JDKRandomGenerator();
the crossover policy used by the algorithm.
/** the crossover policy used by the algorithm. */
private final CrossoverPolicy crossoverPolicy;
the rate of crossover for the algorithm.
/** the rate of crossover for the algorithm. */
private final double crossoverRate;
the mutation policy used by the algorithm.
/** the mutation policy used by the algorithm. */
private final MutationPolicy mutationPolicy;
the rate of mutation for the algorithm.
/** the rate of mutation for the algorithm. */
private final double mutationRate;
the selection policy used by the algorithm.
/** the selection policy used by the algorithm. */
private final SelectionPolicy selectionPolicy;
the number of generations evolved to reach StoppingCondition in the last run.
/** the number of generations evolved to reach {@link StoppingCondition} in the last run. */
private int generationsEvolved = 0;
Create a new genetic algorithm.
Params:
  • crossoverPolicy – The CrossoverPolicy
  • crossoverRate – The crossover rate as a percentage (0-1 inclusive)
  • mutationPolicy – The MutationPolicy
  • mutationRate – The mutation rate as a percentage (0-1 inclusive)
  • selectionPolicy – The SelectionPolicy
Throws:
/** * Create a new genetic algorithm. * @param crossoverPolicy The {@link CrossoverPolicy} * @param crossoverRate The crossover rate as a percentage (0-1 inclusive) * @param mutationPolicy The {@link MutationPolicy} * @param mutationRate The mutation rate as a percentage (0-1 inclusive) * @param selectionPolicy The {@link SelectionPolicy} * @throws OutOfRangeException if the crossover or mutation rate is outside the [0, 1] range */
public GeneticAlgorithm(final CrossoverPolicy crossoverPolicy, final double crossoverRate, final MutationPolicy mutationPolicy, final double mutationRate, final SelectionPolicy selectionPolicy) throws OutOfRangeException { if (crossoverRate < 0 || crossoverRate > 1) { throw new OutOfRangeException(LocalizedFormats.CROSSOVER_RATE, crossoverRate, 0, 1); } if (mutationRate < 0 || mutationRate > 1) { throw new OutOfRangeException(LocalizedFormats.MUTATION_RATE, mutationRate, 0, 1); } this.crossoverPolicy = crossoverPolicy; this.crossoverRate = crossoverRate; this.mutationPolicy = mutationPolicy; this.mutationRate = mutationRate; this.selectionPolicy = selectionPolicy; }
Set the (static) random generator.
Params:
  • random – random generator
/** * Set the (static) random generator. * * @param random random generator */
public static synchronized void setRandomGenerator(final RandomGenerator random) { randomGenerator = random; }
Returns the (static) random generator.
Returns:the static random generator shared by GA implementation classes
/** * Returns the (static) random generator. * * @return the static random generator shared by GA implementation classes */
public static synchronized RandomGenerator getRandomGenerator() { return randomGenerator; }
Evolve the given population. Evolution stops when the stopping condition is satisfied. Updates the generationsEvolved property with the number of generations evolved before the StoppingCondition is satisfied.
Params:
  • initial – the initial, seed population.
  • condition – the stopping condition used to stop evolution.
Returns:the population that satisfies the stopping condition.
/** * Evolve the given population. Evolution stops when the stopping condition * is satisfied. Updates the {@link #getGenerationsEvolved() generationsEvolved} * property with the number of generations evolved before the StoppingCondition * is satisfied. * * @param initial the initial, seed population. * @param condition the stopping condition used to stop evolution. * @return the population that satisfies the stopping condition. */
public Population evolve(final Population initial, final StoppingCondition condition) { Population current = initial; generationsEvolved = 0; while (!condition.isSatisfied(current)) { current = nextGeneration(current); generationsEvolved++; } return current; }
Evolve the given population into the next generation.

  1. Get nextGeneration population to fill from current generation, using its nextGeneration method
  2. Loop until new generation is filled:
  3. Return nextGeneration
Params:
  • current – the current population.
Returns:the population for the next generation.
/** * Evolve the given population into the next generation. * <p> * <ol> * <li>Get nextGeneration population to fill from <code>current</code> * generation, using its nextGeneration method</li> * <li>Loop until new generation is filled:</li> * <ul><li>Apply configured SelectionPolicy to select a pair of parents * from <code>current</code></li> * <li>With probability = {@link #getCrossoverRate()}, apply * configured {@link CrossoverPolicy} to parents</li> * <li>With probability = {@link #getMutationRate()}, apply * configured {@link MutationPolicy} to each of the offspring</li> * <li>Add offspring individually to nextGeneration, * space permitting</li> * </ul> * <li>Return nextGeneration</li> * </ol> * * @param current the current population. * @return the population for the next generation. */
public Population nextGeneration(final Population current) { Population nextGeneration = current.nextGeneration(); RandomGenerator randGen = getRandomGenerator(); while (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) { // select parent chromosomes ChromosomePair pair = getSelectionPolicy().select(current); // crossover? if (randGen.nextDouble() < getCrossoverRate()) { // apply crossover policy to create two offspring pair = getCrossoverPolicy().crossover(pair.getFirst(), pair.getSecond()); } // mutation? if (randGen.nextDouble() < getMutationRate()) { // apply mutation policy to the chromosomes pair = new ChromosomePair( getMutationPolicy().mutate(pair.getFirst()), getMutationPolicy().mutate(pair.getSecond())); } // add the first chromosome to the population nextGeneration.addChromosome(pair.getFirst()); // is there still a place for the second chromosome? if (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) { // add the second chromosome to the population nextGeneration.addChromosome(pair.getSecond()); } } return nextGeneration; }
Returns the crossover policy.
Returns:crossover policy
/** * Returns the crossover policy. * @return crossover policy */
public CrossoverPolicy getCrossoverPolicy() { return crossoverPolicy; }
Returns the crossover rate.
Returns:crossover rate
/** * Returns the crossover rate. * @return crossover rate */
public double getCrossoverRate() { return crossoverRate; }
Returns the mutation policy.
Returns:mutation policy
/** * Returns the mutation policy. * @return mutation policy */
public MutationPolicy getMutationPolicy() { return mutationPolicy; }
Returns the mutation rate.
Returns:mutation rate
/** * Returns the mutation rate. * @return mutation rate */
public double getMutationRate() { return mutationRate; }
Returns the selection policy.
Returns:selection policy
/** * Returns the selection policy. * @return selection policy */
public SelectionPolicy getSelectionPolicy() { return selectionPolicy; }
Returns the number of generations evolved to reach StoppingCondition in the last run.
Returns:number of generations evolved
Since:2.1
/** * Returns the number of generations evolved to reach {@link StoppingCondition} in the last run. * * @return number of generations evolved * @since 2.1 */
public int getGenerationsEvolved() { return generationsEvolved; } }