    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    import org.apache.commons.math.util.FastMath;
    023
    024    /**
    025     * Population of chromosomes which uses elitism (certain percentace of the best
    026     * chromosomes is directly copied to the next generation).
    027     *
    028     * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 ao??t 2010) $
    029     * @since 2.0
    030     */
    031    public class ElitisticListPopulation extends ListPopulation {
    032
    033        /** percentage of chromosomes copied to the next generation */
    034        private double elitismRate = 0.9;
    035
    036        /**
    037         * Creates a new ElitisticListPopulation instance.
    038         *
    039         * @param chromosomes
    040         *            list of chromosomes in the population
    041         * @param populationLimit
    042         *            maximal size of the population
    043         * @param elitismRate
    044         *            how many best chromosomes will be directly transferred to the
    045         *            next generation [in %]
    046         */
    047        public ElitisticListPopulation(List<Chromosome> chromosomes, int populationLimit, double elitismRate) {
    048            super(chromosomes, populationLimit);
    049            this.elitismRate = elitismRate;
    050        }
    051
    052        /**
    053         * Creates a new ListPopulation instance and initializes its inner
    054         * chromosome list.
    055         *
    056         * @param populationLimit maximal size of the population
    057         * @param elitismRate
    058         *            how many best chromosomes will be directly transferred to the
    059         *            next generation [in %]
    060         */
    061        public ElitisticListPopulation(int populationLimit, double elitismRate) {
    062            super(populationLimit);
    063            this.elitismRate = elitismRate;
    064        }
    065
    066        /**
    067         * Start the population for the next generation. The
    068         * <code>{@link #elitismRate}<code> percents of the best
    069         * chromosomes are directly copied to the next generation.
    070         *
    071         * @return the beginnings of the next generation.
    072         */
    073        public Population nextGeneration() {
    074            // initialize a new generation with the same parameters
    075            ElitisticListPopulation nextGeneration = new ElitisticListPopulation(this.getPopulationLimit(), this.getElitismRate());
    076
    077            List<Chromosome> oldChromosomes = this.getChromosomes();
    078            Collections.sort(oldChromosomes);
    079
    080            // index of the last "not good enough" chromosome
    081            int boundIndex = (int) FastMath.ceil((1.0 - this.getElitismRate()) * oldChromosomes.size());
    082            for (int i=boundIndex; i<oldChromosomes.size(); i++) {
    083                nextGeneration.addChromosome(oldChromosomes.get(i));
    084            }
    085            return nextGeneration;
    086        }
    087
    088        /**
    089         * Sets the elitism rate, i.e. how many best chromosomes will be directly
    090         * transferred to the next generation [in %].
    091         *
    092         * @param elitismRate
    093         *            how many best chromosomes will be directly transferred to the
    094         *            next generation [in %]
    095         */
    096        public void setElitismRate(double elitismRate) {
    097            if (elitismRate < 0 || elitismRate > 1)
    098                throw new IllegalArgumentException("Elitism rate has to be in [0,1]");
    099            this.elitismRate = elitismRate;
    100        }
    101
    102        /**
    103         * Access the elitism rate.
    104         * @return the elitism rate
    105         */
    106        public double getElitismRate() {
    107            return this.elitismRate;
    108        }
    109
    110    }