package jcgp.backend.modules.mutator; 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; import jcgp.backend.resources.parameters.BooleanParameter; import jcgp.backend.resources.parameters.DoubleParameter; import jcgp.backend.resources.parameters.Parameter; import jcgp.backend.resources.parameters.ParameterStatus; public class PointMutator implements Mutator { private DoubleParameter mutationRate; private BooleanParameter report; public PointMutator(final Resources resources) { mutationRate = new DoubleParameter(50, "Percent mutation", false, false) { @Override public void validate(Number newValue) { if (newValue.doubleValue() <= 0 || newValue.doubleValue() > 100) { status = ParameterStatus.INVALID; status.setDetails("Mutation rate must be > 0 and <= 100"); } else if ((int) ((newValue.doubleValue() / 100) * (double) resources.nodes()) <= 0) { status = ParameterStatus.WARNING; status.setDetails("With mutation rate " + mutationRate.get() + ", 0 genes will be mutated."); } else { status = ParameterStatus.VALID; } } }; report = new BooleanParameter(false, "Report") { @Override public void validate(Boolean newValue) { // blank } }; } @Override public void mutate(Chromosome chromosome, Resources resources) { int mutations = (int) ((mutationRate.get()) * (((((double) resources.nodes() + resources.outputs()))) / 100)); if (report.get()) resources.reportln("[Mutator] Number of mutations to be performed: " + mutations); for (int i = 0; i < mutations; i++) { MutableElement m = chromosome.getRandomMutableElement(); if (report.get()) resources.report("[Mutator] Mutation " + i + " selected " + m.toString() + ", "); if (m instanceof Output) { if (report.get()) resources.report("changed source from " + ((Output) m).getSource().toString() + " "); m.setConnection(0, chromosome.getRandomConnection()); if (report.get()) resources.reportln("to " + ((Output) m).getSource().toString()); } else if (m instanceof Node) { int geneType = resources.getRandomInt(1 + resources.arity()); if (geneType < 1) { if (report.get()) resources.report("changed function from " + ((Node) m).getFunction().getName() + " "); ((Node) m).setFunction(resources.getRandomFunction()); if (report.get()) resources.reportln("to " + ((Node) m).getFunction().getName()); } else { int connection = resources.getRandomInt(resources.arity()); if (report.get()) resources.report("changed connection " + connection + " from " + ((Node) m).getConnection(connection) + " "); m.setConnection(connection, chromosome.getRandomConnection(((Node) m).getColumn())); if (report.get()) resources.reportln("to " + ((Node) m).getConnection(connection)); } } } } @Override public Parameter[] getLocalParameters() { return new Parameter[] {mutationRate, report}; } @Override public String toString() { return "Point mutation"; } }