/* * 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.*; /** * This genetic operator performs Gaussian mutation across all genes in a * Chromosome. * * @author Klaus Meffert (modified JOONEGAP source) * @since 2.0 */ public class GaussianMutationOperator extends BaseGeneticOperator { /** String containing the CVS revision. Read out via reflection!*/ private static final String CVS_REVISION = "$Revision: 1.25 $"; private double m_deviation; private RandomGenerator m_rg; /** * Constructs a GaussianMutationOperator with a default deviation of 0.05. * Attention: The configuration used is the one set with the static method * Genotype.setConfiguration. * * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 2.0 */ public GaussianMutationOperator() throws InvalidConfigurationException { this(Genotype.getStaticConfiguration()); } /** * Constructs a GaussianMutationOperator with a default deviation of 0.05. * * @param a_config the configuration to use * * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 3.0 */ public GaussianMutationOperator(Configuration a_config) throws InvalidConfigurationException { this(a_config, 0.05d); } /** * Constructs a GaussianMutationOperator with the given deviation. * * @param a_configuration the configuration to use * @param a_deviation sic * * @throws InvalidConfigurationException * * @since 3.0 (since 2.0 without a_configuration) */ public GaussianMutationOperator(final Configuration a_configuration, final double a_deviation) throws InvalidConfigurationException { super(a_configuration); m_deviation = a_deviation; } /** * Executes the operation. * * @param a_population containing chromosomes to be mutated * @param a_candidateChromosomes resulting chromosomes * * @author Klaus Meffert * @since 2.0 */ public void operate(final Population a_population, final List a_candidateChromosomes) { int size = Math.min(getConfiguration().getPopulationSize(), a_population.size()); if (m_rg == null) { RandomGenerator rn = getConfiguration().getRandomGenerator(); m_rg = rn; } for (int i = 0; i < size; i++) { Gene[] genes = a_population.getChromosome(i).getGenes(); IChromosome originalChrom = a_population.getChromosome(i); IChromosome copyOfChromosome = null; // For each Chromosome in the population... // ---------------------------------------- for (int j = 0; j < genes.length; j++) { double nextGaussian = m_rg.nextDouble(); double diff = nextGaussian * m_deviation; // ...take a copy of it... // ----------------------- if (copyOfChromosome == null) { copyOfChromosome = (IChromosome) originalChrom.clone(); // ...add it to the candidate pool... // ---------------------------------- a_candidateChromosomes.add(copyOfChromosome); // ...then Gaussian mutate all its genes genes = copyOfChromosome.getGenes(); // In case monitoring is active, support it. // ----------------------------------------- if (m_monitorActive) { copyOfChromosome.setUniqueIDTemplate(originalChrom.getUniqueID(), 1); } } // Process all atomic elements in the gene. For a StringGene this // would be the length of the string, for an IntegerGene, it is // always one element. // -------------------------------------------------------------- if (genes[j] instanceof CompositeGene) { CompositeGene compositeGene = (CompositeGene) genes[j]; if (m_monitorActive) { compositeGene.setUniqueIDTemplate(originalChrom.getGene(j). getUniqueID(), 1); } for (int k = 0; k < compositeGene.size(); k++) { mutateGene(compositeGene.geneAt(k), diff); if (m_monitorActive) { compositeGene.geneAt(k).setUniqueIDTemplate( ( (ICompositeGene) originalChrom.getGene(j)).geneAt(k). getUniqueID(), 1); } } } else { mutateGene(genes[j], diff); if (m_monitorActive) { genes[j].setUniqueIDTemplate(originalChrom.getGene(j).getUniqueID(), 1); } } } } } /** * Helper: mutate all atomic elements of a gene. * * @param a_gene the gene to be mutated * @param a_percentage the percentage the gene is to be mutated with * * @author Klaus Meffert * @since 2.0 */ private void mutateGene(final Gene a_gene, final double a_percentage) { for (int k = 0; k < a_gene.size(); k++) { // Mutate atomic element by given percentage. // ------------------------------------------ a_gene.applyMutation(k, a_percentage); } } /** * 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; } GaussianMutationOperator op = (GaussianMutationOperator) a_other; if (m_deviation != op.m_deviation) { if (m_deviation > op.m_deviation) { return 1; } else { return -1; } } // Everything is equal. Return zero. // --------------------------------- return 0; } /** * @return the deviation set * * @author Klaus Meffert * @since 3.1 */ public double getDeviation() { return m_deviation; } }