/* * 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.*; /** * The inversion operator randomly selects one chromosomes from the * population and inverses it by randomly picking a splitting locus on which * to swap the first part with the last part of the chromosome. * * @author Klaus Meffert * @since 2.3 */ public class InversionOperator extends BaseGeneticOperator { /** String containing the CVS revision. Read out via reflection!*/ private final static String CVS_REVISION = "$Revision: 1.11 $"; /** * Default constructor.<p> * Attention: The configuration used is the one set with the static method * Genotype.setConfiguration. * * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 2.3 */ public InversionOperator() throws InvalidConfigurationException { this(Genotype.getStaticConfiguration()); } /** * Constructs a new instance of this operator. * * @param a_config the configuration to use * * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 3.0 */ public InversionOperator(Configuration a_config) throws InvalidConfigurationException { super(a_config); } /** * @param a_population the population to operate on * @param a_candidateChromosomes resulting chromosomes * * @author Klaus Meffert * @since 2.3 */ public void operate(final Population a_population, final List a_candidateChromosomes) { // Work out the number of crossovers that should be performed. // ----------------------------------------------------------- int size = Math.min(getConfiguration().getPopulationSize(), a_population.size()); RandomGenerator generator = getConfiguration().getRandomGenerator(); // For the inversion, grab a random chromosome, pick a random // locus (gene location), and then swap that gene and all genes // to the "right" (those with greater loci) of that gene with the left // genes. // ------------------------------------------------------------------- int index1; index1 = generator.nextInt(size); IChromosome chrom1 = a_population.getChromosome(index1); IChromosome firstMate = (IChromosome) chrom1.clone(); // In case monitoring is active, support it. // ----------------------------------------- if (m_monitorActive) { firstMate.setUniqueIDTemplate(chrom1.getUniqueID(), 1); } Gene[] firstGenes = firstMate.getGenes(); int locus = generator.nextInt(firstGenes.length); // Swap the genes. // --------------- Gene[] invertedGenes = new Gene[firstGenes.length]; int index = 0; int len = firstGenes.length; for (int j = locus; j < len; j++) { invertedGenes[index++] = firstGenes[j]; } for (int j = 0; j < locus; j++) { invertedGenes[index++] = firstGenes[j]; } try { firstMate.setGenes(invertedGenes); } catch (InvalidConfigurationException cex) { // Rethrow to have an unchecked exception. // --------------------------------------- throw new Error(cex); } // Add the modified chromosome to the candidate pool so that it'll be // considered for natural selection during the next phase of evolution. // -------------------------------------------------------------------- a_candidateChromosomes.add(firstMate); } /** * Compares the given GeneticOperator to this GeneticOperator. * * @param a_other the instance against which to compare this instance * @return a negative number if this instance is "less than" the given * instance, zero if they are equal to each other, and a positive number if * this is "greater than" the given instance * * @author Klaus Meffert * @since 2.6 */ public int compareTo(final Object a_other) { if (a_other == null) { return 1; } InversionOperator op = (InversionOperator) a_other; // Everything is equal. Return zero. // --------------------------------- return 0; } }