001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licensing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package examples.gp;
011:
012: import java.util.*;
013:
014: import org.jgap.*;
015: import org.jgap.gp.*;
016: import org.jgap.gp.function.*;
017: import org.jgap.gp.impl.*;
018: import org.jgap.gp.terminal.*;
019:
020: /**
021: * Example demonstrating Genetic Programming (GP) capabilities of JGAP.
022: * Also demonstrates usage of ADFs.
023: * The problem is to find a formula for a given truth table (X/Y-pairs).
024: *
025: * @author Klaus Meffert
026: * @since 3.0
027: */
028: public class MathProblem extends GPProblem {
029: /** String containing the CVS revision. Read out via reflection!*/
030: private final static String CVS_REVISION = "$Revision: 1.20 $";
031:
032: public static Variable vx;
033:
034: protected static Float[] x = new Float[20];
035:
036: protected static float[] y = new float[20];
037:
038: public MathProblem(GPConfiguration a_conf)
039: throws InvalidConfigurationException {
040: super (a_conf);
041: }
042:
043: public GPGenotype create() throws InvalidConfigurationException {
044: GPConfiguration conf = getGPConfiguration();
045: Class[] types = {
046: // Return type of result-producing chromosome
047: CommandGene.FloatClass,
048: // Return type of ADF 1
049: CommandGene.FloatClass };
050: Class[][] argTypes = {
051: // Arguments of result-producing chromosome: none
052: {},
053: // Arguments of ADF1: all 3 are float
054: { CommandGene.FloatClass, CommandGene.FloatClass,
055: CommandGene.FloatClass } };
056: CommandGene[][] nodeSets = {
057: {
058: vx = Variable.create(conf, "X",
059: CommandGene.FloatClass),
060: // new Add(conf, CommandGene.FloatClass),
061: // new Add3(conf, CommandGene.FloatClass),
062: // new Subtract(conf, CommandGene.FloatClass),
063: new Multiply(conf, CommandGene.FloatClass),
064: new Multiply3(conf, CommandGene.FloatClass),
065: new Divide(conf, CommandGene.FloatClass),
066: new Sine(conf, CommandGene.FloatClass),
067: new Exp(conf, CommandGene.FloatClass),
068: new Pow(conf, CommandGene.FloatClass),
069: new Terminal(conf, CommandGene.FloatClass,
070: 2.0d, 10.0d, true),
071: new ADF(conf, 1 /*, argTypes[1] */, 3), },
072: // and now the definition of ADF(1)
073: { new Add3(conf, CommandGene.FloatClass), } };
074: Random random = new Random();
075: // Randomly initialize function data (X-Y table) for x^4+x^3+x^2-x
076: // ---------------------------------------------------------------
077: for (int i = 0; i < 20; i++) {
078: float f = 8.0f * (random.nextFloat() - 0.3f);
079: x[i] = new Float(f);
080: y[i] = f * f * f * f + f * f * f + f * f - f;
081: System.out.println(i + ") " + x[i] + " " + y[i]);
082: }
083: // Create genotype with initial population.
084: // ----------------------------------------
085: return GPGenotype.randomInitialGenotype(conf, types, argTypes,
086: nodeSets, 20, true);
087: }
088:
089: /**
090: * Starts the example.
091: *
092: * @param args ignored
093: * @throws Exception
094: *
095: * @author Klaus Meffert
096: * @since 3.0
097: */
098: public static void main(String[] args) throws Exception {
099: System.out.println("Formula to discover: X^4 + X^3 + X^2 - X");
100: GPConfiguration config = new GPConfiguration();
101: config.setGPFitnessEvaluator(new DeltaGPFitnessEvaluator());
102: config.setMaxInitDepth(4);
103: config.setPopulationSize(1000);
104: config.setMaxCrossoverDepth(8);
105: config
106: .setFitnessFunction(new MathProblem.FormulaFitnessFunction());
107: config.setStrictProgramCreation(true);
108: GPProblem problem = new MathProblem(config);
109: GPGenotype gp = problem.create();
110: gp.setVerboseOutput(true);
111: gp.evolve(800);
112: gp.outputSolution(gp.getAllTimeBest());
113: problem.showTree(gp.getAllTimeBest(), "mathproblem_best.png");
114: }
115:
116: public static class FormulaFitnessFunction extends
117: GPFitnessFunction {
118: protected double evaluate(final IGPProgram a_subject) {
119: return computeRawFitness(a_subject);
120: }
121:
122: public double computeRawFitness(final IGPProgram ind) {
123: double error = 0.0f;
124: Object[] noargs = new Object[0];
125: for (int i = 0; i < 20; i++) {
126: vx.set(x[i]);
127: try {
128: double result = ind.execute_float(0, noargs);
129: error += Math.abs(result - y[i]);
130: } catch (ArithmeticException ex) {
131: System.out.println("x = " + x[i].floatValue());
132: System.out.println(ind);
133: throw ex;
134: }
135: }
136: if (error < 0.001) {
137: error = 0.0d;
138: }
139: return error;
140: }
141: }
142: }
|