/*
 * This file is part of JGAP.
 *
 * JGAP offers a dual license model containing the LGPL as well as the MPL.
 *
 * For licensing information please see the file license.txt included with JGAP
 * or have a look at the top of class org.jgap.Chromosome which representatively
 * includes the JGAP license policy applicable for any file delivered with JGAP.
 */
package org.jgap.impl;

import java.util.*;
import org.jgap.*;
import org.jgap.util.*;

/**
 * Implementation of a NaturalSelector that is suited for being processed after
 * genetic operators have been executed. It takes all chromosomes with no
 * fitness value computed to the next generation. Then it takes the top n
 * chromosomes from the remaining input into the next generation.
 * Which chromosomes are the best is decided by evaluating their fitness value.
 *
 * @author Klaus Meffert
 * @since 3.2
 */
public class StandardPostSelector
    extends NaturalSelector implements ICloneable {
  /** String containing the CVS revision. Read out via reflection!*/
  private final static String CVS_REVISION = "$Revision: 1.4 $";

  /**
   * Stores the chromosomes to be taken into account for selection
   */
  private Population m_chromosomes;

  /**
   * Indicated whether the list of added chromosomes needs sorting
   */
  private boolean m_needsSorting;

  /**
   * Comparator that is only concerned about fitness values
   */
  private FitnessValueComparator m_fitnessValueComparator;

  /**
   * Default constructor.

* Attention: The configuration used is the one set with the static method * Genotype.setConfiguration. * * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 3.2 */ public StandardPostSelector() throws InvalidConfigurationException { this(Genotype.getStaticConfiguration()); } /** * Constructor. * * @param a_config the configuration to use * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 3.2 */ public StandardPostSelector(final Configuration a_config) throws InvalidConfigurationException { super(a_config); m_chromosomes = new Population(a_config); m_needsSorting = false; m_fitnessValueComparator = new FitnessValueComparator(); } /** * Add a Chromosome instance to this selector's working pool of Chromosomes. * * @param a_chromosomeToAdd the specimen to add to the pool * * @author Klaus Meffert * @since 3.2 */ protected void add(final IChromosome a_chromosomeToAdd) { // New chromosome, insert it into the sorted collection of chromosomes. // -------------------------------------------------------------------- a_chromosomeToAdd.setIsSelectedForNextGeneration(false); m_chromosomes.addChromosome(a_chromosomeToAdd); // Indicate that the list of chromosomes to add needs sorting. // ----------------------------------------------------------- m_needsSorting = true; } /** * Selects a given number of Chromosomes from the pool that will move on * to the next generation population. This selection will be guided by the * fitness values. The chromosomes with the best fitness value win. * * @param a_from_pop the population the Chromosomes will be selected from * @param a_to_pop the population the Chromosomes will be added to * @param a_howManyToSelect the number of Chromosomes to select * * @author Klaus Meffert * @since 1.1 */ public void select(final int a_howManyToSelect, final Population a_from_pop, final Population a_to_pop) { if (a_from_pop != null) { int popSize = a_from_pop.size(); if (popSize < 1) { throw new IllegalStateException("Population size must be greater 0"); } for (int i = 0; i < popSize; i++) { add(a_from_pop.getChromosome(i)); } } int canBeSelected; int chromsSize = m_chromosomes.size(); if (chromsSize < 1) { throw new IllegalStateException( "Number of chromosomes must be greater 0"); } if (a_howManyToSelect > chromsSize) { canBeSelected = chromsSize; } else { canBeSelected = a_howManyToSelect; } int neededSize = a_howManyToSelect; // First select all chromosomes with no fitness value computed. // ------------------------------------------------------------ Iterator it = m_chromosomes.iterator(); while (it.hasNext()) { IChromosome c = (IChromosome)it.next(); if (Math.abs(c.getFitnessValueDirectly() - FitnessFunction.NO_FITNESS_VALUE) < FitnessFunction.DELTA) { a_to_pop.addChromosome(c); it.remove(); canBeSelected--; if (canBeSelected < 1) { break; } } } // Sort the collection of chromosomes previously added for evaluation. // Only do this if necessary. // ------------------------------------------------------------------- if (m_needsSorting && canBeSelected > 0) { Collections.sort(m_chromosomes.getChromosomes(), m_fitnessValueComparator); m_needsSorting = false; } // To select a chromosome, we just go thru the sorted list. // -------------------------------------------------------- IChromosome selectedChromosome; for (int i = 0; i < canBeSelected; i++) { selectedChromosome = m_chromosomes.getChromosome(i); selectedChromosome.setIsSelectedForNextGeneration(true); a_to_pop.addChromosome(selectedChromosome); } int toAdd; toAdd = neededSize - a_to_pop.size(); // Add existing chromosomes to fill up the return // result to contain the desired number of chromosomes. // ---------------------------------------------------- for (int i = 0; i < toAdd; i++) { selectedChromosome = m_chromosomes.getChromosome(i % chromsSize); selectedChromosome.setIsSelectedForNextGeneration(true); a_to_pop.addChromosome(selectedChromosome); } } /** * Empties out the working pool of chromosomes. * * @author Klaus Meffert * @since 3.2 */ public void empty() { // Clear the list of chromosomes. // ------------------------------ m_chromosomes.getChromosomes().clear(); m_needsSorting = false; } /** * @return always true as no chromosome can be returnd multiple times * * @author Klaus Meffert * @since 3.2 */ public boolean returnsUniqueChromosomes() { return true; } public boolean equals(Object a_o) { if (a_o == null) { return false; } StandardPostSelector other = (StandardPostSelector) a_o; if (!m_fitnessValueComparator.getClass().getName().equals( other.m_fitnessValueComparator.getClass().getName())) { return false; } if (!m_chromosomes.equals(other.m_chromosomes)) { return false; } return true; } public Object clone() { try { StandardPostSelector sel = new StandardPostSelector(getConfiguration()); sel.m_needsSorting = m_needsSorting; return sel; } catch (Throwable t) { throw new CloneException(t); } } }

Ads help maintain this website.