[jgap-users] FW: Program compiles, but immediately crashes
Brought to you by:
klausikm
From: Jason C. <tec...@ho...> - 2009-02-18 15:44:19
|
I realized that I responded directly to Klaus rather than the list. Replying to list so the information in the last post can be shared with others... <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Klaus, Thank you for your response. Right before receiving your response, I added a dummy variable terminal to my program and it no longer crashes. This is good news. I can kind of understand why. I am guessing that the program first tries experiments with the smallest trees possible, which will start out as 1 node. So the first attempt will be a single terminal accepting no inputs. Well, if it cannot find a single terminal with the correct return type (boolean in this case), then the program just crashes? You are correct about the function input types being declared in the function constructor. For the case of variables, the return type is declared in the constructor: "Also notice, that the last parameter of the variable denotes the return type of the variable, i.e Float.class (or: CommandGene.FloatClass). " (from your document referenced below) RE: <QUOTE>: As creating a GP program is a stochastic process, a missing terminal of a needed type increases the number of tries to find a CORRECT GP program (one that complies to the specifications in the configuration regarding input types and return types). Adding a boolean terminal should only bring disadvantages to you if your fitness function is time-consuming (like with RobocodeJGAP where whole Java classes are compiled for each individual). Could you give me some more details why you see limitations here for your planned implementation? </QUOTE> That makes sense, but in my case I might not be able to come up with a useful boolean variable relevant to my problem (maybe / maybe not, I am still in the GA development phase). The concern is that if I cannot come up with a boolean variable, it will slow down my fitness function because the variable will need to be set on every increment. Not only that, but for a boolean variable, it will also double the search space (not sure if it actually doubles due to nature of GA, but it will definitely increase the search space, no?). Second, I had a new question about this: <QUOTE FROM DOCUMENT REFERENCED BELOW>: The first array, types, defines the return type of the sub programs (which will be outlined soon). In our example, we only have one sub program, thus the length of the arrays is one. The parameter CommandGene.FloatClass expresses that the return type is Float.Class. This is because CommandGene.FloatClass is just a convenient, speaking definition of Float.Class (it is equivalent). </QUOTE> I don't understand the purpose of subprograms. You mention that subprograms will be outlined soon, but I was not sure if you mean soon as in later in the document or soon as in later when you have time. It appears that maybe they have not been documented yet because I am not sure what they are for, what the purpose of a subprogram is. I am guessing that subprograms are used to limit the search space. Given sufficient computational power, we could just throw all functions and variables into one program and let the computer figure out the relationship with enough time. However, subprograms allow us to isolate the relevant variables and functions (which we know are related) from the other parts (variables and functions) of the program which we know are not related. So subprograms allow us to reduce the search space by running smaller isolated searches in place of one larger search. It allows us to bring in "expert" knowledge in order to reduce the search space? Is that correct, I am completely guessing here. I have some other questions, but I will try to further search the e-mail archive for them. By the way, I found the e-mail archive on sourceforge, but I don't see a search function. So it seems that I have to manually read e-mails one by one to find what I am looking for? Is this correct? I think it might improve communication in the development and user community if an online forum were to replace the e-mail system. Whatever is most convenient for you works, but the message board forum might be more organized. Not sure, but I think google offers free message board hosting... Anyway, thanks for your help, I look forward to using JGAP!! -Jason From: jg...@kl... To: tec...@ho... Subject: RE: [jgap-users] Program compiles, but immediately crashes Date: Wed, 18 Feb 2009 08:27:34 +0100 Jason, I understand your concern. And you are right that the LesserThan/GreaterThan returns a boolean value. BTW: Your definition states that LesserThan/GreaterThan accepts boolean INPUT values (they always return boolean, but the input types are specified by the input parameters of the constructor). So this has to be changed to correspond to the variable return type. The GP doc. page has been extended by me yesterday. I will work on it in the future to reflect discussions. Back to your concern: The current algorithms sometimes requires a terminal and sometimes a function of a specific return type X. To avoid problems you have to add a boolean terminal to your configuration. I will see if this can be avoided by adapting the GP algorithms. For your understanding: As creating a GP program is a stochastic process, a missing terminal of a needed type increases the number of tries to find a CORRECT GP program (one that complies to the specifications in the configuration regarding input types and return types). Adding a boolean terminal should only bring disadvantages to you if your fitness function is time-consuming (like with RobocodeJGAP where whole Java classes are compiled for each individual). Could you give me some more details why you see limitations here for your planned implementation? Best Klaus www.klaus-meffert.com From: Jason Criss [mailto:tec...@ho...] Sent: Tuesday, February 17, 2009 7:54 PM To: jg...@kl... Subject: RE: [jgap-users] Program compiles, but immediately crashes Klaus, Thank you for your response and you are correct that there are no terminals defined with return type Boolean.class. However, why is this necessary? The variable instances are of return type float, however when these are fed into the function commands, the output is boolean. So all the program needs to do is ensure that a function block of return type boolean is at the root of the tree and the overall result of tree evaluation will be boolean. Requiring the terminals to be of type boolean seems like an unnecessary constraint. Is there a way I can hack my program to get it to with with the setup that I currently have? Forcing boolean terminals will seriously limit my planned implementation. Thanks, Jason From: jg...@kl... To: tec...@ho...; jga...@li... Subject: RE: [jgap-users] Program compiles, but immediately crashes Date: Tue, 17 Feb 2009 17:31:54 +0100 Jason, good question. The error message states that there is no TERMINAL of return type Boolean.class. In your declaration, you only have functions with child type Boolean.class (also see http://jgap.sourceforge.net/doc/genetic_programming.html, which I will extend to clarify things better). Please see org.jgap.gp.terminal for a list of terminal available. Best Klaus www.klaus-meffert.com PS: Your source code arrived in good shape. An alternative would be to attach it (in case it's not too big, which shouldn't be the case for any exemplary source code). From: Jason Criss [mailto:tec...@ho...] Sent: Tuesday, February 17, 2009 7:49 AM To: jga...@li... Subject: [jgap-users] Program compiles, but immediately crashes I am new to JGap and a bit stumped by this error: Exception in thread "main" org.jgap.InvalidConfigurationException: java.lang.RuntimeException: Chromosome (depth 1, index 0) requires a terminal of return type class java.lang.Boolean (sub return type 0) but there is no such node available at org.jgap.gp.impl.GPGenotype.randomInitialGenotype(GPGenotype.java:391) at org.jgap.gp.impl.GPGenotype.randomInitialGenotype(GPGenotype.java:316) at org.jgap.gp.impl.GPGenotype.randomInitialGenotype(GPGenotype.java:273) at org.jgap.gp.impl.GPGenotype.randomInitialGenotype(GPGenotype.java:225) at SimpleGAP.create(SimpleGAP.java:142) at SimpleGAP.main(SimpleGAP.java:175) Caused by: java.lang.RuntimeException: Chromosome (depth 1, index 0) requires a terminal of return type class java.lang.Boolean (sub return type 0) but there is no such node available at org.jgap.gp.impl.ProgramChromosome.selectNode(ProgramChromosome.java:506) at org.jgap.gp.impl.ProgramChromosome.growOrFullNode(ProgramChromosome.java:573) at org.jgap.gp.impl.ProgramChromosome.growOrFullNode(ProgramChromosome.java:653) at org.jgap.gp.impl.ProgramChromosome.growOrFullNode(ProgramChromosome.java:653) at org.jgap.gp.impl.ProgramChromosome.growOrFull(ProgramChromosome.java:272) at org.jgap.gp.impl.GPProgram.growOrFull(GPProgram.java:208) at org.jgap.gp.impl.DefaultProgramCreator.create(DefaultProgramCreator.java:35) at org.jgap.gp.impl.GPPopulation.create(GPPopulation.java:513) at org.jgap.gp.impl.GPPopulation.create(GPPopulation.java:315) at org.jgap.gp.impl.GPPopulation.create(GPPopulation.java:241) at org.jgap.gp.impl.DefaultPopulationCreator.initialize(DefaultPopulationCreator.java:68) at org.jgap.gp.impl.GPGenotype.randomInitialGenotype(GPGenotype.java:388) ... 5 more I don't understand why I am getting the error above. It is true that all chromosomes should return type bool, but there are nodes which return type bool, such as any of these: new IfElse(conf, CommandGene.BooleanClass), new And(conf, CommandGene.BooleanClass), new Or(conf), new Not(conf), new LesserThan(conf, CommandGene.BooleanClass), new GreaterThan(conf, CommandGene.BooleanClass) Defined below in create() function NodeSets. The variables defined are of type float and will be supplied parameters external to the program. I want to compare these using function commands LessThan or GreaterThan which will take the float values, do the comparison and return a bool which will be combined via boolean logic and ultimately represent the overall result of the chomosome. Can someone please tell me how to do this? Pasted below is my entire program, but it's basically just slightly modified from the MathProblem example. Anyone know of a cleaner way of sharing code such as below? Not sure how it will be processed by the e-mail system... /* * This file is part of JGAP. * * JGAP offers a dual license model containing the LGPL as well as the MPL. * * For licensing information please see the file license.txt included with JGAP * or have a look at the top of class org.jgap.Chromosome which representatively * includes the JGAP license policy applicable for any file delivered with JGAP. */ import java.util.*; import org.jgap.*; import org.jgap.gp.*; import org.jgap.gp.function.*; import org.jgap.gp.impl.*; import org.jgap.gp.terminal.*; /** * Example demonstrating Genetic Programming (GP) capabilities of JGAP. * Also demonstrates usage of ADF's.<br> * The problem is to find a formula for a given truth table (X/Y-pairs). * <p> * <ul> * <li>The setup of the GP is done in method main and specifically in method * create()</li> * <li>The problem solving process is started via gp.evolve(800) in the main * method, with 800 the maximum number of evolutions to take place. * <li>The evaluation of the evolved formula is done in fitness function * FormulaFitnessFunction, which is implemented in this class, MathProblem * </ul> * <br> * For details, please see the mentioned methods and the fitness function. * <p> * @author Klaus Meffert * @since 3.0 */ public class SimpleGAP extends GPProblem { /** String containing the CVS revision. Read out via reflection!*/ private final static String CVS_REVISION = "$Revision: 1.24 $"; public static Variable vx, demod, clkfreq, datafreq, dtsangout; protected static Float[] x = new Float[20]; protected static float[] y = new float[20]; public SimpleGAP(GPConfiguration a_conf) throws InvalidConfigurationException { super(a_conf); } /** * This method is used for setting up the commands and terminals that can be * used to solve the problem. * In this example an ADF (an automatically defined function) is used for * demonstration purpuses. Using an ADF is optional. If you want to use one, * care about the places marked with "ADF-relevant:" below. If you do not want * to use an ADF, please remove the below places (and reduce the outer size of * the arrays "types", "argTypes" and "nodeSets" to one). * Please notice, that the variables types, argTypes and nodeSets correspond * to each other: they have the same number of elements and the element at * the i'th index of each variable corresponds to the i'th index of the other * variables! * * @return GPGenotype * @throws InvalidConfigurationException */ public GPGenotype create() throws InvalidConfigurationException { GPConfiguration conf = getGPConfiguration(); // At first, we define the return type of the GP program. // ------------------------------------------------------ Class[] types = { // Return type of result-producing chromosome CommandGene.BooleanClass, // ADF-relevant: // Return type of ADF 1 CommandGene.FloatClass}; // Then, we define the arguments of the GP parts. Normally, only for ADF's // there is a specification here, otherwise it is empty as in first case. // ----------------------------------------------------------------------- Class[][] argTypes = { // Arguments of result-producing chromosome: none {}, // ADF-relevant: // Arguments of ADF1: all 3 are float {CommandGene.FloatClass, CommandGene.FloatClass, CommandGene.FloatClass} }; // Next, we define the set of available GP commands and terminals to use. // Please see package org.jgap.gp.function and org.jgap.gp.terminal // You can easily add commands and terminals of your own. // ---------------------------------------------------------------------- CommandGene[][] nodeSets = { { // We use a variable that can be set in the fitness function. // ---------------------------------------------------------- vx = Variable.create(conf, "X", CommandGene.FloatClass), demod = Variable.create(conf, "demod", CommandGene.FloatClass), clkfreq = Variable.create(conf, "clkfreq", CommandGene.FloatClass), datafreq = Variable.create(conf, "datafreq", CommandGene.FloatClass), dtsangout = Variable.create(conf, "dtsangout", CommandGene.FloatClass), new IfElse(conf, CommandGene.BooleanClass), new And(conf, CommandGene.BooleanClass), new Or(conf), new Not(conf), new LesserThan(conf, CommandGene.BooleanClass), new GreaterThan(conf, CommandGene.BooleanClass), // ADF-relevant: // Construct a reference to the ADF defined in the second nodeset // which has index 1 (second parameter of ADF-constructor). // Furthermore, the ADF expects three input parameters (see argTypes[1]) new ADF(conf, 1 , 3), }, // ADF-relevant: // and now the definition of ADF(1) { new Add3(conf, CommandGene.FloatClass), } }; // Here, we define the expected (optimal) output we want to achieve by the // function/formula to evolve by the GP. // ----------------------------------------------------------------------- Random random = new Random(); // Randomly initialize function data (X-Y table) for x^4+x^3+x^2-x // --------------------------------------------------------------- for (int i = 0; i < 20; i++) { float f = 8.0f * (random.nextFloat() - 0.3f); x[i] = new Float(f); y[i] = f * f * f * f + f * f * f + f * f - f; System.out.println(i + ") " + x[i] + " " + y[i]); } // Create genotype with initial population. Here, we use the declarations // made above: // Use one result-producing chromosome (index 0) with return type float // (see types[0]), no argument (argTypes[0]) and several valid commands and // terminals (nodeSets[0]). Contained in the node set is an ADF at index 1 // in the node set (as declared with the second parameter during // ADF-construction: new ADF(..,1,..)). // The ADF has return type float (types[1]), three input parameters of type // float (argTypes[1]) and exactly one function: Add3 (nodeSets[1]). // ------------------------------------------------------------------------ return GPGenotype.randomInitialGenotype(conf, types, argTypes, nodeSets, 20, true); } /** * Starts the example. * * @param args ignored * @throws Exception * * @author Klaus Meffert * @since 3.0 */ public static void main(String[] args) throws Exception { System.out.println("Formula to discover: X^4 + X^3 + X^2 - X"); // Setup the algorithm's parameters. // --------------------------------- GPConfiguration config = new GPConfiguration(); // We use a delta fitness evaluator because we compute a defect rate, not // a point score! // ---------------------------------------------------------------------- config.setGPFitnessEvaluator(new DeltaGPFitnessEvaluator()); config.setMaxInitDepth(4); config.setPopulationSize(1000); config.setMaxCrossoverDepth(8); config.setFitnessFunction(new SimpleGAP.FormulaFitnessFunction()); config.setStrictProgramCreation(true); GPProblem problem = new SimpleGAP(config); // Create the genotype of the problem, i.e., define the GP commands and // terminals that can be used, and constrain the structure of the GP // program. // -------------------------------------------------------------------- GPGenotype gp = problem.create(); gp.setVerboseOutput(true); // Start the computation with maximum 800 evolutions. // if a satisfying result is found (fitness value almost 0), JGAP stops // earlier automatically. // -------------------------------------------------------------------- gp.evolve(800); // Print the best solution so far to the console. // ---------------------------------------------- gp.outputSolution(gp.getAllTimeBest()); // Create a graphical tree of the best solution's program and write it to // a PNG file. // ---------------------------------------------------------------------- problem.showTree(gp.getAllTimeBest(), "mathproblem_best.png"); } /** * Fitness function for evaluating the produced fomulas, represented as GP * programs. The fitness is computed by calculating the result (Y) of the * function/formula for integer inputs 0 to 20 (X). The sum of the differences * between expected Y and actual Y is the fitness, the lower the better (as * it is a defect rate here). */ public static class FormulaFitnessFunction extends GPFitnessFunction { protected double evaluate(final IGPProgram a_subject) { return computeRawFitness(a_subject); } public double computeRawFitness(final IGPProgram ind) { double error = 0.0f; Object[] noargs = new Object[0]; // Evaluate function for input numbers 0 to 20. // -------------------------------------------- for (int i = 0; i < 20; i++) { // Provide the variable X with the input number. // See method create(), declaration of "nodeSets" for where X is // defined. // ------------------------------------------------------------- vx.set(0.0); demod.set(0.0); clkfreq.set(1.0); datafreq.set(2.0); dtsangout.set(3.0); try { // Execute the GP program representing the function to be evolved. // As in method create(), the return type is declared as float (see // declaration of array "types"). // ---------------------------------------------------------------- boolean result = ind.execute_boolean(0, noargs); // Sum up the error between actual and expected result to get a defect // rate. // ------------------------------------------------------------------- //error += Math.abs(result - y[i]); // If the error is too high, stop evlauation and return worst error // possible. // ---------------------------------------------------------------- if (Double.isInfinite(error)) { return Double.MAX_VALUE; } } catch (ArithmeticException ex) { // This should not happen, some illegal operation was executed. // ------------------------------------------------------------ System.out.println("x = " + x[i].floatValue()); System.out.println(ind); throw ex; } } // In case the error is small enough, consider it perfect. // ------------------------------------------------------- if (error < 0.001) { error = 0.0d; } return error; } } } Windows Live™: E-mail. Chat. Share. Get more ways to connect. See how it works. Windows Live™: E-mail. Chat. Share. Get more ways to connect. See how it works. See how Windows Mobile brings your life together—at home, work, or on the go. See Now _________________________________________________________________ Stay up to date on your PC, the Web, and your mobile phone with Windows Live. http://clk.atdmt.com/MRT/go/msnnkwxp1020093185mrt/direct/01/ |