001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. 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 package org.apache.commons.math.genetics; 018 019 import java.util.Collections; 020 import java.util.List; 021 022 /** 023 * Population of chromosomes which uses elitism (certain percentace of the best 024 * chromosomes is directly copied to the next generation). 025 * 026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ 027 * @since 2.0 028 */ 029 public class ElitisticListPopulation extends ListPopulation { 030 031 /** percentage of chromosomes copied to the next generation */ 032 private double elitismRate = 0.9; 033 034 /** 035 * Creates a new ElitisticListPopulation instance. 036 * 037 * @param chromosomes 038 * list of chromosomes in the population 039 * @param populationLimit 040 * maximal size of the population 041 * @param elitismRate 042 * how many best chromosomes will be directly transferred to the 043 * next generation [in %] 044 */ 045 public ElitisticListPopulation(List<Chromosome> chromosomes, int populationLimit, double elitismRate) { 046 super(chromosomes, populationLimit); 047 this.elitismRate = elitismRate; 048 } 049 050 /** 051 * Creates a new ListPopulation instance and initializes its inner 052 * chromosome list. 053 * 054 * @param populationLimit maximal size of the population 055 * @param elitismRate 056 * how many best chromosomes will be directly transferred to the 057 * next generation [in %] 058 */ 059 public ElitisticListPopulation(int populationLimit, double elitismRate) { 060 super(populationLimit); 061 this.elitismRate = elitismRate; 062 } 063 064 /** 065 * Start the population for the next generation. The 066 * <code>{@link #elitismRate}<code> percents of the best 067 * chromosomes are directly copied to the next generation. 068 * 069 * @return the beginnings of the next generation. 070 */ 071 public Population nextGeneration() { 072 // initialize a new generation with the same parameters 073 ElitisticListPopulation nextGeneration = new ElitisticListPopulation(this.getPopulationLimit(), this.getElitismRate()); 074 075 List<Chromosome> oldChromosomes = this.getChromosomes(); 076 Collections.sort(oldChromosomes); 077 078 // index of the last "not good enough" chromosome 079 int boundIndex = (int) Math.ceil((1.0 - this.getElitismRate()) * oldChromosomes.size()); 080 for (int i=boundIndex; i<oldChromosomes.size(); i++) { 081 nextGeneration.addChromosome(oldChromosomes.get(i)); 082 } 083 return nextGeneration; 084 } 085 086 /** 087 * Sets the elitism rate, i.e. how many best chromosomes will be directly 088 * transferred to the next generation [in %]. 089 * 090 * @param elitismRate 091 * how many best chromosomes will be directly transferred to the 092 * next generation [in %] 093 */ 094 public void setElitismRate(double elitismRate) { 095 if (elitismRate < 0 || elitismRate > 1) 096 throw new IllegalArgumentException("Elitism rate has to be in [0,1]"); 097 this.elitismRate = elitismRate; 098 } 099 100 /** 101 * Access the elitism rate. 102 * @return the elitism rate 103 */ 104 public double getElitismRate() { 105 return this.elitismRate; 106 } 107 108 }