/home/ooechs/Ecj2Java/src/ac/essex/ooechs/ecj/ecj2java/example/problems/MathsProblem.java
|
package ac.essex.ooechs.ecj.ecj2java.example.problems;
import ec.gp.GPProblem;
import ec.gp.GPIndividual;
import ec.gp.koza.KozaFitness;
import ec.simple.SimpleProblemForm;
import ec.EvolutionState;
import ec.Individual;
import ec.util.Parameter;
import ac.essex.ooechs.ecj.ecj2java.JavaWriter;
import ac.essex.ooechs.ecj.ecj2java.example.data.DoubleData;
import java.io.File;
import java.io.IOException;
/**
*
* Uses GP to solve simple maths problems.
*
* <p/>
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version,
* provided that any use properly credits the author.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details at http://www.gnu.org
* </p>
*
* @author Olly Oechsle, University of Essex, Date: 05-Sep-2006
* @version 1.0
*/
public class MathsProblem extends GPProblem implements SimpleProblemForm {
public DoubleData input;
public double x;
public Object protoClone() throws CloneNotSupportedException {
MathsProblem newobj = (MathsProblem) (super.protoClone());
newobj.input = (DoubleData) (input.protoClone());
return newobj;
}
public void setup(final EvolutionState state, final Parameter base) {
// very important, remember this
super.setup(state, base);
// set up the input ( equally important if you don't want
input = (DoubleData) state.parameters.getInstanceForParameterEq(base.push(P_DATA), null, DoubleData.class);
input.setup(state, base.push(P_DATA));
}
public void evaluate(final EvolutionState state, final Individual ind, final int threadnum) {
// ensure we only evaluate the individual once
if (!ind.evaluated) {
float fitness = 0.0f;
int TP = 0;
for (int i = 0; i < 1000; i++) {
// set up the X variable
x = i;
// produce an expected output, in this case the square of x
double expected = (x * x) + 1;
// process the individual
((GPIndividual) ind).trees[0].child.eval(state, threadnum, input, stack, ((GPIndividual) ind), this);
// and get the individual's result
double received = input.x;
// add the difference to the expected value. Fitness of 0 is perfect.
fitness += Math.abs(expected - received);
// work out if it is "close enough" for a TP
if (isSimilarTo(expected, received, 0.05)) TP++;
}
// convert to KozaFitness, which expects 0 as perfect fitness
KozaFitness f = ((KozaFitness) ind.fitness);
f.setStandardizedFitness(state, fitness);
f.hits = TP;
ind.evaluated = true;
System.out.print(".");
}
}
public boolean isSimilarTo(double number1, double number2, double threshold) {
double difference = Math.abs(number1 - number2);
return (difference / number1) < threshold;
}
static int counter = 0;
public void describe(final Individual ind, final EvolutionState state, final int threadnum, final int log, final int verbosity) {
state.output.println("\n\nBest Individual", verbosity, log);
KozaFitness f = ((KozaFitness) ind.fitness);
counter++;
/**
* Create a ECJ2Java Writer here, with the following parameters:
*/
String classPackage = "ac.essex.ooechs.ecj2java.example.individuals";
String className = "MathsSolution" + counter;
String functionSignature = "public double calculate(double x)";
String comment = "Fitness: " + f.hits;
JavaWriter writer = new JavaWriter(className, functionSignature, comment, classPackage);
/**
* Decide where the Java file is to be saved:
*/
File saveTo = new File("/home/ooechs/Ecj2Java/src/ac/essex/ooechs/ecj2java/example/individuals/");
/**
* Generate and save the file
*/
try {
writer.saveJavaCode((GPIndividual) ind, saveTo);
} catch (IOException e) {
e.printStackTrace();
}
/**
* And that's all there is to it!
*/
System.out.println("TP: " + f.hits);
System.out.println("Fitness: " + f.standardizedFitness());
}
}