/* * 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.distr.*; /** * A implementation of the IPopulationMerger interface that merges two * populations as specified based on the fitness function, that is, the n * fittest chromosomes are returned in the new population, where n is supplied * by parameter. * * @author Henrique Goulart * @since 2.0 */ public class FittestPopulationMerger implements IPopulationMerger { /** String containing the CVS revision. Read out via reflection!*/ private final static String CVS_REVISION = "$Revision: 1.17 $"; public Population mergePopulations(final Population a_population1, final Population a_population2, final int a_new_population_size) { /**@todo check if configurations of both pops are equal resp. * their fitness evaluators!*/ try { // All the chromosomes are placed in the first population for sorting. a_population1.addChromosomes(a_population2); // A sorting is made according to the chromosomes fitness values // See the private class FitnessChromosomeComparator below to understand. List allChromosomes = a_population1.getChromosomes(); Collections.sort(allChromosomes, new FitnessChromosomeComparator( a_population1.getConfiguration())); //Then a new population is created and the fittest "a_new_population_size" //chromosomes are added. Chromosome[] chromosomes = (Chromosome[]) allChromosomes.toArray(new Chromosome[0]); Population mergedPopulation = new Population(a_population1. getConfiguration(), a_new_population_size); for (int i = 0; i < a_new_population_size && i < chromosomes.length; i++) { mergedPopulation.addChromosome(chromosomes[i]); } // Return the merged population. // ----------------------------- return mergedPopulation; } catch (InvalidConfigurationException iex) { // This should never happen throw new IllegalStateException(iex.getMessage()); } } /** * This class is used to sort the merged population chromosomes * according to their fitness values. For convenience, the * sorting is done in a reverse way, so this comparator * returns 1 if the first chromosome has a LOWER fitness value. * * @author Henrique Goulart * @since 2.0 */ private class FitnessChromosomeComparator implements Comparator { private transient Configuration m_config; // Reference to the current FitnessEvaluator Object, used for comparing // chromosomes. private FitnessEvaluator m_fEvaluator; public FitnessChromosomeComparator(Configuration a_config) { m_config = a_config; m_fEvaluator = m_config.getFitnessEvaluator(); } /** * Implements the compare method using the fitness function. * The comparation is implemented in a reverse way to make the * merging easier (the list of chromosomes is sorted in a * descending fitness value order). * * @param a_o1 first IChromosome to compare * @param a_o2 second IChromosome to compare * @return @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(final Object a_o1, final Object a_o2) { // The two objects passed are always Chromosomes, so a cast must be made. IChromosome chr1 = (IChromosome) a_o1; IChromosome chr2 = (IChromosome) a_o2; // Reverse comparison. if (m_fEvaluator.isFitter(chr2.getFitnessValue(), chr1.getFitnessValue())) { return 1; } else if (m_fEvaluator.isFitter(chr1.getFitnessValue(), chr2.getFitnessValue())) { return -1; } else { return 0; } } } }