package jcgp.backend.modules.mutator; import jcgp.backend.parameters.BooleanParameter; import jcgp.backend.parameters.IntegerParameter; import jcgp.backend.population.Chromosome; import jcgp.backend.population.MutableElement; import jcgp.backend.population.Node; import jcgp.backend.population.Output; import jcgp.backend.resources.Resources; /** * Point mutator *

* In point mutation, a number of random genes * is picked and mutated until all required * mutations have been performed. The actual number * of genes to be mutated can be defined in any * arbitrary way. * * @author Eduardo Pedroni * */ public abstract class PointMutator extends Mutator { protected IntegerParameter genesMutated; protected BooleanParameter report; @Override public void mutate(Chromosome chromosome, Resources resources) { if (report.get()) resources.reportln("[Mutator] Number of mutations to be performed: " + genesMutated.get()); // for however many genes must be mutated for (int i = 0; i < genesMutated.get(); i++) { MutableElement m = chromosome.getRandomMutableElement(); if (report.get()) resources.report("[Mutator] Mutation " + i + " selected " + m + ", "); // outputs and nodes are mutated differently if (m instanceof Output) { if (report.get()) resources.report("changed source from " + ((Output) m).getSource() + " "); // outputs are easy, simply set to a different random connection, any will do m.setConnection(0, chromosome.getRandomConnection()); if (report.get()) resources.reportln("to " + ((Output) m).getSource()); } else if (m instanceof Node) { /* nodes are more complicated, first we must decide whether to mutate the function * or a connection * we do this by generating a random int between 0 and 1 + arity */ int geneType = resources.getRandomInt(1 + resources.arity()); // if the int is less than 1, mutate function, else mutate connections if (geneType < 1) { if (report.get()) resources.report("changed function from " + ((Node) m).getFunction() + " "); ((Node) m).setFunction(resources.getRandomFunction()); if (report.get()) resources.reportln("to " + ((Node) m).getFunction()); } else { // if we decided to mutate connection, subtract 1 from geneType so it fits into the arity range geneType -= 1; if (report.get()) resources.report("changed connection " + geneType + " from " + ((Node) m).getConnection(geneType) + " "); m.setConnection(geneType, chromosome.getRandomConnection(((Node) m).getColumn())); if (report.get()) resources.reportln("to " + ((Node) m).getConnection(geneType)); } } } } }