package jcgp.backend.modules.mutator; import jcgp.backend.function.Function; import jcgp.backend.modules.ModuleStatus; import jcgp.backend.parameters.DoubleParameter; import jcgp.backend.parameters.Parameter; import jcgp.backend.population.Chromosome; import jcgp.backend.population.MutableElement; import jcgp.backend.population.Node; import jcgp.backend.population.Output; import jcgp.JCGP.Resources; public class PointMutator implements Mutator { private DoubleParameter mutationRate; private ModuleStatus status = ModuleStatus.READY; public PointMutator() { mutationRate = new DoubleParameter(0.5, "Percent mutation", false, false) { @Override public void validate(double newValue) { // TODO this } }; } @Override public void mutate(Chromosome chromosome, Resources resources) { int mutations = (int) Math.ceil(((mutationRate.get()) * ((((resources.getDouble("nodes")) + (resources.getDouble("outputs")))) / (double) 100))); for (int i = 0; i < mutations; i++) { MutableElement m = chromosome.getRandomMutableElement(); if (m instanceof Output) { m.setConnection(0, chromosome.getRandomConnection()); } else if (m instanceof Node) { int geneType = resources.getRandomInt(1 + resources.getInt("arity")); if (geneType < 1) { Function f = resources.getRandomFunction(); ((Node) m).setFunction(f); } else { m.setConnection(resources.getRandomInt(resources.getInt("arity")), chromosome.getRandomConnection(((Node) m).getColumn())); } } } } @Override public Parameter[] getLocalParameters() { return new Parameter[] {mutationRate}; } @Override public String toString() { return "Point mutation"; } @Override public ModuleStatus getStatus(Resources resources) { if (mutationRate.get() <= 0 || mutationRate.get() > 100) { status = ModuleStatus.ERROR; status.setDetails("Mutation rate must be > 0 and <= 100"); } else if ((int) ((mutationRate.get() / 100) * resources.getDouble("nodes")) > 0) { status = ModuleStatus.WARNING; status.setDetails("With mutation rate " + mutationRate.get() + ", no mutations will occur."); } else { status = ModuleStatus.READY; status.setDetails(""); } return status; } }