/* * 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 examples.monalisa.core; import java.util.*; import java.util.List; import java.awt.*; import org.jgap.*; import org.jgap.impl.*; /** * Translates a polygon of each chromosome in a random direction. * * @author Yann N. Dauphin * @since 3.4 */ public class PolygonMutationOperator extends MutationOperator { /** String containing the CVS revision. Read out via reflection!*/ private final static String CVS_REVISION = "$Revision: 1.3 $"; public PolygonMutationOperator(final Configuration a_config, final int a_desiredMutationRate) throws InvalidConfigurationException { super(a_config, a_desiredMutationRate); } @Override public void operate(final Population a_population, final List a_candidateChromosomes) { if (a_population == null || a_candidateChromosomes == null) { // Population or candidate chromosomes list empty: // nothing to do. // ----------------------------------------------- return; } if (getMutationRate() == 0 && getMutationRateCalc() == null) { // If the mutation rate is set to zero and dynamic mutation rate is // disabled, then we don't perform any mutation. // ---------------------------------------------------------------- return; } GAConfiguration conf = (GAConfiguration) getConfiguration(); // Determine the mutation rate. If dynamic rate is enabled, then // calculate it using the IUniversalRateCalculator instance. // Otherwise, go with the mutation rate set upon construction. // ------------------------------------------------------------- RandomGenerator generator = conf.getRandomGenerator(); // It would be inefficient to create copies of each Chromosome just // to decide whether to mutate them. Instead, we only make a copy // once we've positively decided to perform a mutation. // ---------------------------------------------------------------- int size = Math.min(conf.getPopulationSize(), a_population.size()); IGeneticOperatorConstraint constraint = conf.getJGAPFactory(). getGeneticOperatorConstraint(); for (int i = 0; i < size; i++) { IChromosome chrom = a_population.getChromosome(i); Gene[] genes = chrom.getGenes(); IChromosome copyOfChromosome = null; // For each Chromosome in the population... // ---------------------------------------- /* Find a polygon to mutate */ int polygon = generator.nextInt(conf.getMaxPolygons()); boolean mutate = (generator.nextInt(getMutationRate()) == 0); if (mutate) { // Verify that crossover allowed. // ------------------------------ /**@todo move to base class, refactor*/ if (constraint != null) { List v = new Vector(); v.add(chrom); if (!constraint.isValid(a_population, v, this)) { continue; } } // Now that we want to actually modify the Chromosome, // let's make a copy of it (if we haven't already) and // add it to the candidate chromosomes so that it will // be considered for natural selection during the next // phase of evolution. Then we'll set the gene's value // to a random value as the implementation of our // "mutation" of the gene. // --------------------------------------------------- if (copyOfChromosome == null) { // ...take a copy of it... // ----------------------- copyOfChromosome = (IChromosome) chrom.clone(); // ...add it to the candidate pool... // ---------------------------------- a_candidateChromosomes.add(copyOfChromosome); // ...then mutate all its genes... // ------------------------------- genes = copyOfChromosome.getGenes(); } Polygon poly = conf.getPhenotypeExpresser().expressPolygon(chrom, polygon); int dx = generator.nextInt(conf.getTarget().getWidth() / 8); int dy = generator.nextInt(conf.getTarget().getHeight() / 8); poly.translate(dx, dy); int pos = GAInitialChromosomeFactory.getNumberOfColorGenesPerPolygon() + polygon * GAInitialChromosomeFactory.getNumberOfGenesPerPolygon(); for (int p = 0; p < GAInitialChromosomeFactory.POINTS; p++) { if (poly.xpoints[p] > 0 && poly.xpoints[p] < conf.getTarget().getWidth()) { genes[pos++].setAllele(new Integer(poly.xpoints[p])); } if (poly.ypoints[p] > 0 && poly.ypoints[p] < conf.getTarget().getWidth()) { genes[pos++].setAllele(new Integer(poly.ypoints[p])); } } } } } }