ElitisticListPopulation.java

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

  18. import java.util.Collections;
  19. import java.util.List;

  20. import org.apache.commons.math4.legacy.exception.NotPositiveException;
  21. import org.apache.commons.math4.legacy.exception.NullArgumentException;
  22. import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
  23. import org.apache.commons.math4.legacy.exception.OutOfRangeException;
  24. import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
  25. import org.apache.commons.math4.core.jdkmath.JdkMath;

  26. /**
  27.  * Population of chromosomes which uses elitism (certain percentage of the best
  28.  * chromosomes is directly copied to the next generation).
  29.  *
  30.  * @since 2.0
  31.  */
  32. public class ElitisticListPopulation extends ListPopulation {

  33.     /** percentage of chromosomes copied to the next generation. */
  34.     private double elitismRate = 0.9;

  35.     /**
  36.      * Creates a new {@link ElitisticListPopulation} instance.
  37.      *
  38.      * @param chromosomes list of chromosomes in the population
  39.      * @param populationLimit maximal size of the population
  40.      * @param elitismRate how many best chromosomes will be directly transferred to the next generation [in %]
  41.      * @throws NullArgumentException if the list of chromosomes is {@code null}
  42.      * @throws NotPositiveException if the population limit is not a positive number (< 1)
  43.      * @throws NumberIsTooLargeException if the list of chromosomes exceeds the population limit
  44.      * @throws OutOfRangeException if the elitism rate is outside the [0, 1] range
  45.      */
  46.     public ElitisticListPopulation(final List<Chromosome> chromosomes, final int populationLimit,
  47.                                    final double elitismRate)
  48.         throws NullArgumentException, NotPositiveException, NumberIsTooLargeException, OutOfRangeException {

  49.         super(chromosomes, populationLimit);
  50.         setElitismRate(elitismRate);
  51.     }

  52.     /**
  53.      * Creates a new {@link ElitisticListPopulation} instance and initializes its inner chromosome list.
  54.      *
  55.      * @param populationLimit maximal size of the population
  56.      * @param elitismRate how many best chromosomes will be directly transferred to the next generation [in %]
  57.      * @throws NotPositiveException if the population limit is not a positive number (&lt; 1)
  58.      * @throws OutOfRangeException if the elitism rate is outside the [0, 1] range
  59.      */
  60.     public ElitisticListPopulation(final int populationLimit, final double elitismRate)
  61.         throws NotPositiveException, OutOfRangeException {

  62.         super(populationLimit);
  63.         setElitismRate(elitismRate);
  64.     }

  65.     /**
  66.      * Start the population for the next generation. The <code>{@link #elitismRate}</code>
  67.      * percents of the best chromosomes are directly copied to the next generation.
  68.      *
  69.      * @return the beginnings of the next generation.
  70.      */
  71.     @Override
  72.     public Population nextGeneration() {
  73.         // initialize a new generation with the same parameters
  74.         ElitisticListPopulation nextGeneration =
  75.                 new ElitisticListPopulation(getPopulationLimit(), getElitismRate());

  76.         final List<Chromosome> oldChromosomes = getChromosomeList();
  77.         Collections.sort(oldChromosomes);

  78.         // index of the last "not good enough" chromosome
  79.         int boundIndex = (int) JdkMath.ceil((1.0 - getElitismRate()) * oldChromosomes.size());
  80.         for (int i = boundIndex; i < oldChromosomes.size(); i++) {
  81.             nextGeneration.addChromosome(oldChromosomes.get(i));
  82.         }
  83.         return nextGeneration;
  84.     }

  85.     /**
  86.      * Sets the elitism rate, i.e. how many best chromosomes will be directly transferred to the next generation [in %].
  87.      *
  88.      * @param elitismRate how many best chromosomes will be directly transferred to the next generation [in %]
  89.      * @throws OutOfRangeException if the elitism rate is outside the [0, 1] range
  90.      */
  91.     public void setElitismRate(final double elitismRate) throws OutOfRangeException {
  92.         if (elitismRate < 0 || elitismRate > 1) {
  93.             throw new OutOfRangeException(LocalizedFormats.ELITISM_RATE, elitismRate, 0, 1);
  94.         }
  95.         this.elitismRate = elitismRate;
  96.     }

  97.     /**
  98.      * Access the elitism rate.
  99.      * @return the elitism rate
  100.      */
  101.     public double getElitismRate() {
  102.         return this.elitismRate;
  103.     }
  104. }