/home/ooechs/Ecj2Java/src/ac/essex/ooechs/ecj/ecj2java/example/problems/MathsProblem.java

package ac.essex.ooechs.ecj.ecj2java.example.problems; 
 
import ac.essex.ooechs.ecj.ecj2java.JavaWriter; 
import ac.essex.ooechs.ecj.ecj2java.example.data.DoubleData; 
import ec.EvolutionState; 
import ec.Individual; 
import ec.gp.GPIndividual; 
import ec.gp.GPProblem; 
import ec.gp.koza.KozaFitness; 
import ec.simple.SimpleProblemForm; 
import ec.util.Parameter; 
 
import java.io.File; 
import java.io.IOException; 
 
/** 
 * Uses GP to solve simple maths problems. 
 * Note that you will have to change the paths specified so the Java 
 * file can be saved properly. 
 * <p/> 
 * <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 { 
 
    // CHANGE THESE SETTINGS ACCORDING TO YOUR PREFERENCES 
    public static final String classPackage = "ac.essex.ooechs.ecj.ecj2java.example.individuals"; 
    public static final String outputDirectory = "/home/ooechs/Ecj2Java/src/ac/essex/ooechs/ecj/ecj2java/example/individuals/"; 
    // END SETTINGS 
 
    public DoubleData input; 
 
    public double x; 
    public double y; 
 
    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)); 
 
    } 
 
    int dotCount = 0; 
 
    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; 
 
            // x and y are public variables so the GP nodes 
            // have access to them outside this method. 
            for (y = 0; y <= 50; y+=1) { 
                for (x = 0; x <= 50; x+=1) { 
 
                    // lets get the problem to work out the 
                    // pythagoras equation. The code in this file 
                    // may seem a little contrived - we already know 
                    // the pythagoras equation! But if you were 
                    // to feed your program results from the real world 
                    // it may be able to find an equation to describe them 
                    // that you didn't already know. 
                    double expected = Math.sqrt((x * x) + (y * y)); 
 
                    // this is the code to run 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); 
            if (fitness == 1.0f) fitness = 0.0f; 
            f.setStandardizedFitness(state, fitness); 
 
            f.hits = TP; 
            ind.evaluated = true; 
 
            dotCount++; 
            // only print out every 20th dot (save filling the screen with dots!) 
            if (dotCount % 20 == 0) 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 className = "MathsSolution" + counter; 
        String functionSignature = "public double calculate(double x, double y)"; 
        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(outputDirectory); 
 
        /** 
         * 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("Total Error: " + f.standardizedFitness()); 
 
    } 
 
 
}