package jcgp.backend.modules.mutator;
import jcgp.backend.parameters.BooleanParameter;
import jcgp.backend.parameters.IntegerParameter;
import jcgp.backend.population.Chromosome;
import jcgp.backend.population.Mutable;
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;
/**
* For internal use only, initialises the resources field.
*
* @param resources the experiment's resources.
*/
protected PointMutator(Resources resources) {
super(resources);
}
@Override
public void mutate(Chromosome chromosome) {
if (report.get()) getResources().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++) {
Mutable m = chromosome.getRandomMutable();
if (report.get()) getResources().report("[Mutator] Mutation " + i + " selected " + m + ", ");
// outputs and nodes are mutated differently
if (m instanceof Output) {
if (report.get()) getResources().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()) getResources().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 = getResources().getRandomInt(1 + getResources().arity());
// if the int is less than 1, mutate function, else mutate connections
if (geneType < 1) {
if (report.get()) getResources().report("changed function from " + ((Node) m).getFunction() + " ");
((Node) m).setFunction(getResources().getRandomFunction());
if (report.get()) getResources().reportln("to " + ((Node) m).getFunction());
} else {
// if we decided to mutate connection, subtract 1 from geneType so it fits into the arity range
geneType--;
if (report.get()) getResources().report("changed connection " + geneType + " from " + ((Node) m).getConnection(geneType) + " ");
m.setConnection(geneType, chromosome.getRandomConnection(((Node) m).getColumn()));
if (report.get()) getResources().reportln("to " + ((Node) m).getConnection(geneType));
}
}
}
}
}