Clover coverage report - JGAP 3.1
Coverage timestamp: Mo Dez 11 2006 21:16:18 CET
file stats: LOC: 270   Methods: 11
NCLOC: 116   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
BestChromosomesSelector.java 100% 100% 100% 100%
coverage
 1    /*
 2    * This file is part of JGAP.
 3    *
 4    * JGAP offers a dual license model containing the LGPL as well as the MPL.
 5    *
 6    * For licencing information please see the file license.txt included with JGAP
 7    * or have a look at the top of class org.jgap.Chromosome which representatively
 8    * includes the JGAP license policy applicable for any file delivered with JGAP.
 9    */
 10    package org.jgap.impl;
 11   
 12    import java.util.*;
 13    import org.jgap.*;
 14   
 15    /**
 16    * Implementation of a NaturalSelector that takes the top n chromosomes into
 17    * the next generation. n can be specified. Which chromosomes are the best is
 18    * decided by evaluating their fitness value.
 19    *
 20    * @author Klaus Meffert
 21    * @since 1.1
 22    */
 23    public class BestChromosomesSelector
 24    extends NaturalSelector {
 25    /** String containing the CVS revision. Read out via reflection!*/
 26    private final static String CVS_REVISION = "$Revision: 1.41 $";
 27   
 28    /**
 29    * Stores the chromosomes to be taken into account for selection
 30    */
 31    private Population m_chromosomes;
 32   
 33    /**
 34    * Allows or disallows doublette chromosomes to be added to the selector
 35    */
 36    private boolean m_doublettesAllowed;
 37   
 38    /**
 39    * Indicated whether the list of added chromosomes needs sorting
 40    */
 41    private boolean m_needsSorting;
 42   
 43    /**
 44    * Comparator that is only concerned about fitness values
 45    */
 46    private FitnessValueComparator m_fitnessValueComparator;
 47   
 48    private BestChromosomesSelectorConfig m_config = new
 49    BestChromosomesSelectorConfig();
 50   
 51    /**
 52    * Default constructor.<p>
 53    * Attention: The configuration used is the one set with the static method
 54    * Genotype.setConfiguration.
 55    * @throws InvalidConfigurationException
 56    *
 57    * @author Klaus Meffert
 58    * @since 1.1
 59    */
 60  1 public BestChromosomesSelector()
 61    throws InvalidConfigurationException {
 62  1 this(Genotype.getStaticConfiguration());
 63    }
 64   
 65    /**
 66    * Using original rate of 1.0
 67    * @param a_config the configuration to use
 68    * @throws InvalidConfigurationException
 69    *
 70    * @author Klaus Meffert
 71    * @since 3.0
 72    */
 73  1113 public BestChromosomesSelector(final Configuration a_config)
 74    throws InvalidConfigurationException {
 75  1113 this(a_config, 1.0d);
 76    }
 77   
 78  3511 public BestChromosomesSelector(final Configuration a_config,
 79    final double a_originalRate)
 80    throws InvalidConfigurationException {
 81  3511 super(a_config);
 82  3511 m_chromosomes = new Population(a_config);
 83  3511 m_needsSorting = false;
 84  3511 m_doublettesAllowed = false;
 85  3511 setOriginalRate(a_originalRate);
 86  3511 m_fitnessValueComparator = new FitnessValueComparator();
 87    }
 88   
 89    /**
 90    * Add a Chromosome instance to this selector's working pool of Chromosomes.
 91    * @param a_chromosomeToAdd the specimen to add to the pool
 92    *
 93    * @author Klaus Meffert
 94    * @since 1.1
 95    */
 96  3742 protected void add(final IChromosome a_chromosomeToAdd) {
 97    // If opted-in: Check if chromosome already added
 98    // This speeds up the process by orders of magnitude but could lower the
 99    // quality of evolved results because of fewer Chromosome's used!!!
 100  3742 if (!getDoubletteChromosomesAllowed()
 101    && m_chromosomes.getChromosomes().contains(a_chromosomeToAdd)) {
 102  980 return;
 103    }
 104    // New chromosome, insert it into the sorted collection of chromosomes
 105  2762 a_chromosomeToAdd.setIsSelectedForNextGeneration(false);
 106  2762 m_chromosomes.addChromosome(a_chromosomeToAdd);
 107    // Indicate that the list of chromosomes to add needs sorting.
 108    // -----------------------------------------------------------
 109  2762 m_needsSorting = true;
 110    }
 111   
 112    /**
 113    * Selects a given number of Chromosomes from the pool that will move on
 114    * to the next generation population. This selection will be guided by the
 115    * fitness values. The chromosomes with the best fitness value win.
 116    *
 117    * @param a_from_pop the population the Chromosomes will be selected from
 118    * @param a_to_pop the population the Chromosomes will be added to
 119    * @param a_howManyToSelect the number of Chromosomes to select
 120    *
 121    * @author Klaus Meffert
 122    * @since 1.1
 123    */
 124  38 public void select(final int a_howManyToSelect,
 125    final Population a_from_pop,
 126    final Population a_to_pop) {
 127  38 if (a_from_pop != null) {
 128  28 int popSize = a_from_pop.size();
 129  28 for (int i = 0; i < popSize; i++) {
 130  3725 add(a_from_pop.getChromosome(i));
 131    }
 132    }
 133  38 int canBeSelected;
 134  38 int chromsSize = m_chromosomes.size();
 135  38 if (a_howManyToSelect > chromsSize) {
 136  11 canBeSelected = chromsSize;
 137    }
 138    else {
 139  27 canBeSelected = a_howManyToSelect;
 140    }
 141  38 int neededSize = a_howManyToSelect;
 142  38 double origRate;
 143  38 origRate = m_config.m_originalRate;
 144  38 if (origRate < 1.0d) {
 145  2 canBeSelected = (int) Math.round( (double) canBeSelected *
 146    origRate);
 147  2 if (canBeSelected < 1) {
 148  1 canBeSelected = 1;
 149    }
 150    }
 151    // Sort the collection of chromosomes previously added for evaluation.
 152    // Only do this if necessary.
 153    // -------------------------------------------------------------------
 154  38 if (m_needsSorting) {
 155  34 Collections.sort(m_chromosomes.getChromosomes(),
 156    m_fitnessValueComparator);
 157  34 m_needsSorting = false;
 158    }
 159    // To select a chromosome, we just go thru the sorted list.
 160    // --------------------------------------------------------
 161  38 IChromosome selectedChromosome;
 162  38 for (int i = 0; i < canBeSelected; i++) {
 163  2735 selectedChromosome = m_chromosomes.getChromosome(i);
 164  2735 selectedChromosome.setIsSelectedForNextGeneration(true);
 165  2735 a_to_pop.addChromosome(selectedChromosome);
 166    }
 167  38 if (getDoubletteChromosomesAllowed()) {
 168  17 int toAdd;
 169  17 toAdd = neededSize - a_to_pop.size();
 170    // Add existing Chromosome's to fill up the return
 171    // result to contain the desired number of Chromosome's.
 172    // -----------------------------------------------------
 173  17 for (int i = 0; i < toAdd; i++) {
 174    /**@todo add ramdomization*/
 175  4 selectedChromosome = m_chromosomes.getChromosome(i % chromsSize);
 176  4 selectedChromosome.setIsSelectedForNextGeneration(true);
 177  4 a_to_pop.addChromosome(selectedChromosome);
 178    }
 179    }
 180    }
 181   
 182    /**
 183    * Empties out the working pool of Chromosomes.
 184    *
 185    * @author Klaus Meffert
 186    * @since 1.1
 187    */
 188  30 public void empty() {
 189    // clear the list of chromosomes
 190    // -----------------------------
 191  30 m_chromosomes.getChromosomes().clear();
 192  30 m_needsSorting = false;
 193    }
 194   
 195    /**
 196    * Determines whether doublette chromosomes may be added to the selector or
 197    * will be ignored.
 198    * @param a_doublettesAllowed true: doublette chromosomes allowed to be
 199    * added to the selector. FALSE: doublettes will be ignored and not added
 200    *
 201    * @author Klaus Meffert
 202    * @since 2.0
 203    */
 204  2410 public void setDoubletteChromosomesAllowed(
 205    final boolean a_doublettesAllowed) {
 206  2410 m_doublettesAllowed = a_doublettesAllowed;
 207    }
 208   
 209    /**
 210    * @return true: doublette chromosomes allowed to be added to the selector
 211    *
 212    * @author Klaus Meffert
 213    * @since 2.0
 214    */
 215  3785 public boolean getDoubletteChromosomesAllowed() {
 216  3785 return m_doublettesAllowed;
 217    }
 218   
 219    /**
 220    * @return always true as no Chromosome can be returnd multiple times
 221    *
 222    * @author Klaus Meffert
 223    * @since 2.0
 224    */
 225  2 public boolean returnsUniqueChromosomes() {
 226  2 return true;
 227    }
 228   
 229    /**
 230    * Setting this parameter controls how many chromosomes of the original
 231    * population will be considered for selection to the next population. If
 232    * the value is 1 then the whole original population is considered, if it is
 233    * 0.5 only half of the chromosomes are considered. If doublettes are allowed,
 234    * then a number of chromosomes missing (number of to be selected minus number
 235    * selected) will be added.
 236    * @param a_originalRate the rate of how many of the original chromosomes
 237    * will be selected according to BestChromosomeSelector's strategy. The rest
 238    * (non-original) of the chromosomes is added as duplicates
 239    *
 240    * @author Klaus Meffert
 241    * @since 2.0
 242    */
 243  3521 public void setOriginalRate(final double a_originalRate) {
 244  3521 if (a_originalRate < 0.0d || a_originalRate > 1.0d) {
 245  2 throw new IllegalArgumentException("Original rate must be greater than"
 246    + " zero and not greater than one!");
 247    }
 248  3519 m_config.m_originalRate = a_originalRate;
 249    }
 250   
 251    /**
 252    *
 253    * @return see setOriginalRate
 254    *
 255    * @author Klaus Meffert
 256    * @since 2.0
 257    */
 258  1 public double getOriginalRate() {
 259  1 return m_config.m_originalRate;
 260    }
 261   
 262    class BestChromosomesSelectorConfig
 263    implements java.io.Serializable {
 264    /**
 265    * The rate of original Chromosomes selected. This is because we otherwise
 266    * would always return the original input as output
 267    */
 268    public double m_originalRate;
 269    }
 270    }