View Javadoc
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  
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.apache.commons.math4.legacy.exception.NotPositiveException;
23  import org.apache.commons.math4.legacy.exception.NullArgumentException;
24  import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
25  import org.apache.commons.math4.legacy.exception.OutOfRangeException;
26  import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
27  import org.apache.commons.math4.core.jdkmath.JdkMath;
28  
29  /**
30   * Population of chromosomes which uses elitism (certain percentage of the best
31   * chromosomes is directly copied to the next generation).
32   *
33   * @since 2.0
34   */
35  public class ElitisticListPopulation extends ListPopulation {
36  
37      /** percentage of chromosomes copied to the next generation. */
38      private double elitismRate = 0.9;
39  
40      /**
41       * Creates a new {@link ElitisticListPopulation} instance.
42       *
43       * @param chromosomes list of chromosomes in the population
44       * @param populationLimit maximal size of the population
45       * @param elitismRate how many best chromosomes will be directly transferred to the next generation [in %]
46       * @throws NullArgumentException if the list of chromosomes is {@code null}
47       * @throws NotPositiveException if the population limit is not a positive number (< 1)
48       * @throws NumberIsTooLargeException if the list of chromosomes exceeds the population limit
49       * @throws OutOfRangeException if the elitism rate is outside the [0, 1] range
50       */
51      public ElitisticListPopulation(final List<Chromosome> chromosomes, final int populationLimit,
52                                     final double elitismRate)
53          throws NullArgumentException, NotPositiveException, NumberIsTooLargeException, OutOfRangeException {
54  
55          super(chromosomes, populationLimit);
56          setElitismRate(elitismRate);
57      }
58  
59      /**
60       * Creates a new {@link ElitisticListPopulation} instance and initializes its inner chromosome list.
61       *
62       * @param populationLimit maximal size of the population
63       * @param elitismRate how many best chromosomes will be directly transferred to the next generation [in %]
64       * @throws NotPositiveException if the population limit is not a positive number (&lt; 1)
65       * @throws OutOfRangeException if the elitism rate is outside the [0, 1] range
66       */
67      public ElitisticListPopulation(final int populationLimit, final double elitismRate)
68          throws NotPositiveException, OutOfRangeException {
69  
70          super(populationLimit);
71          setElitismRate(elitismRate);
72      }
73  
74      /**
75       * Start the population for the next generation. The <code>{@link #elitismRate}</code>
76       * percents of the best chromosomes are directly copied to the next generation.
77       *
78       * @return the beginnings of the next generation.
79       */
80      @Override
81      public Population nextGeneration() {
82          // initialize a new generation with the same parameters
83          ElitisticListPopulation nextGeneration =
84                  new ElitisticListPopulation(getPopulationLimit(), getElitismRate());
85  
86          final List<Chromosome> oldChromosomes = getChromosomeList();
87          Collections.sort(oldChromosomes);
88  
89          // index of the last "not good enough" chromosome
90          int boundIndex = (int) JdkMath.ceil((1.0 - getElitismRate()) * oldChromosomes.size());
91          for (int i = boundIndex; i < oldChromosomes.size(); i++) {
92              nextGeneration.addChromosome(oldChromosomes.get(i));
93          }
94          return nextGeneration;
95      }
96  
97      /**
98       * Sets the elitism rate, i.e. how many best chromosomes will be directly transferred to the next generation [in %].
99       *
100      * @param elitismRate how many best chromosomes will be directly transferred to the next generation [in %]
101      * @throws OutOfRangeException if the elitism rate is outside the [0, 1] range
102      */
103     public void setElitismRate(final double elitismRate) throws OutOfRangeException {
104         if (elitismRate < 0 || elitismRate > 1) {
105             throw new OutOfRangeException(LocalizedFormats.ELITISM_RATE, elitismRate, 0, 1);
106         }
107         this.elitismRate = elitismRate;
108     }
109 
110     /**
111      * Access the elitism rate.
112      * @return the elitism rate
113      */
114     public double getElitismRate() {
115         return this.elitismRate;
116     }
117 }