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 (< 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 }