diff --git a/src/eva2/gui/GOEPanel.java b/src/eva2/gui/GOEPanel.java index a82cf207..721bcb32 100644 --- a/src/eva2/gui/GOEPanel.java +++ b/src/eva2/gui/GOEPanel.java @@ -221,6 +221,7 @@ public class GOEPanel extends JPanel implements ItemListener { // System.out.println("Copying " + BeanInspector.toString(source)); SerializedObject so = new SerializedObject(source); result = so.getObject(); + so=null; } catch (Exception ex) { System.err.println("GenericObjectEditor: Problem making backup object"); System.err.println(source.getClass().getName()); diff --git a/src/eva2/gui/GenericArrayEditor.java b/src/eva2/gui/GenericArrayEditor.java index 075e64f9..318a5210 100644 --- a/src/eva2/gui/GenericArrayEditor.java +++ b/src/eva2/gui/GenericArrayEditor.java @@ -114,6 +114,7 @@ implements PropertyEditor { try { SerializedObject so = new SerializedObject(addObj); addObj = so.getObject(); + so=null; if (selected != -1) { m_ListModel.insertElementAt(addObj, selected); } else { diff --git a/src/eva2/server/go/individuals/AbstractEAIndividual.java b/src/eva2/server/go/individuals/AbstractEAIndividual.java index 92f100db..45a6f50c 100644 --- a/src/eva2/server/go/individuals/AbstractEAIndividual.java +++ b/src/eva2/server/go/individuals/AbstractEAIndividual.java @@ -949,7 +949,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java. if ((i+1) < b.length) sb.append(separator); } } else if (individual instanceof InterfaceDataTypeProgram) { - InterfaceProgram[] b = ((InterfaceDataTypeProgram)individual).getProgramData(); + InterfaceProgram[] b = ((InterfaceDataTypeProgram)individual).getProgramDataWithoutUpdate(); for (int i = 0; i < b.length; i++) { sb.append(b[i].getStringRepresentation()); if ((i+1) < b.length) sb.append(separator); diff --git a/src/eva2/server/go/individuals/GPIndividualProgramData.java b/src/eva2/server/go/individuals/GPIndividualProgramData.java index 10ef1f00..3206f8b6 100644 --- a/src/eva2/server/go/individuals/GPIndividualProgramData.java +++ b/src/eva2/server/go/individuals/GPIndividualProgramData.java @@ -27,7 +27,7 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int protected GPArea[] m_Area; protected double m_InitFullGrowRatio = 0.5; protected int m_InitDepth = 4; - protected int m_maxDepth = 8; + protected int m_maxAllowedDepth = 8; protected boolean m_CheckMaxDepth = true; public GPIndividualProgramData() { @@ -58,7 +58,7 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int } this.m_InitFullGrowRatio = individual.m_InitFullGrowRatio; this.m_InitDepth = individual.m_InitDepth; - this.m_maxDepth = individual.m_maxDepth; + this.m_maxAllowedDepth = individual.m_maxAllowedDepth; this.m_CheckMaxDepth = individual.m_CheckMaxDepth; // cloning the members of AbstractEAIndividual @@ -90,7 +90,7 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int if (individual instanceof GPIndividualProgramData) { GPIndividualProgramData indy = (GPIndividualProgramData) individual; //@todo Eigendlich k�nnte ich noch die Areas vergleichen - if (this.m_maxDepth != indy.m_maxDepth) + if (this.m_maxAllowedDepth != indy.m_maxAllowedDepth) return false; if ((this.m_Genotype == null) || (indy.m_Genotype == null)) return false; @@ -134,9 +134,13 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int this.m_Phenotype = new AbstractGPNode[this.m_Genotype.length]; for (int i = 0; i < this.m_Genotype.length; i++) { this.m_Phenotype[i] = (AbstractGPNode)this.m_Genotype[i].clone(); - if ((this.m_CheckMaxDepth) && (this.m_Phenotype[i].isMaxDepthViolated(this.m_maxDepth))) { - //System.out.println("Trying to meet the Target Depth!"); - this.m_Phenotype[i].repairMaxDepth(this.m_Area[i], this.m_maxDepth); + // if (!m_Phenotype[0].checkDepth(0)) { + // System.err.println("error... " + m_Genotype[0].checkDepth(0)); + // } + + if ((this.m_CheckMaxDepth) && (this.m_Phenotype[i].isMaxDepthViolated(this.m_maxAllowedDepth))) { + System.err.println("Trying to meet the Target Depth! " + this.m_Phenotype[i].isMaxDepthViolated(this.m_maxAllowedDepth) + " "+ m_Phenotype[i].getMaxDepth()); + this.m_Phenotype[i].repairMaxDepth(this.m_Area[i], this.m_maxAllowedDepth); //System.out.println("TragetDepth: " + this.m_TargetDepth + " : " + this.m_Program.getMaxDepth()); } } @@ -148,7 +152,8 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int * @return InterfaceProgram[] representing the Program. */ public InterfaceProgram[] getProgramDataWithoutUpdate() { - return this.m_Phenotype; + if (this.m_Phenotype==null) return getProgramData(); + else return this.m_Phenotype; } /** This method allows you to set the program phenotype. @@ -244,6 +249,7 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int */ public void SetPGenotype(AbstractGPNode[] b) { this.m_Genotype = b; + this.m_Phenotype=null; } /** This method will allow the user to set the current program 'genotype'. @@ -252,28 +258,41 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int */ public void SetPGenotype(AbstractGPNode b, int i) { this.m_Genotype[i] = b; + m_Genotype[i].updateDepth(0); +// System.out.println("Setting pheno of depth " + b.getMaxDepth() + " " + b.getStringRepresentation()); + this.m_Phenotype=null; } - /** This method performs a simple one element mutation on the program + /** + * This method performs a simple one element mutation on the program */ public void defaultMutate() { - ArrayList allNodes = new ArrayList(); for (int i = 0; i < this.m_Genotype.length; i++) { - this.m_Genotype[i].addNodesTo(allNodes); - AbstractGPNode nodeToMutate = (AbstractGPNode) allNodes.get(RNG.randomInt(0, allNodes.size()-1)); - if (nodeToMutate.getParent() == null) { + AbstractGPNode nodeToMutate = this.m_Genotype[i].getRandomNode(); + if (nodeToMutate.getParent() == null) { // mutate at root this.defaultInit(null); } else { AbstractGPNode parent = nodeToMutate.getParent(); - AbstractGPNode newNode = (AbstractGPNode)(((AbstractGPNode)this.m_Area[i].getRandomNode().clone())); - newNode.setDepth(nodeToMutate.getDepth()); - newNode.initGrow(this.m_Area[i], this.m_maxDepth); - parent.setNode(newNode, nodeToMutate); + if (m_CheckMaxDepth && (nodeToMutate.getDepth()==m_maxAllowedDepth)) { // mutate with a constant + AbstractGPNode newNode = (AbstractGPNode)(((AbstractGPNode)this.m_Area[i].getRandomNodeWithArity(0).clone())); + newNode.setDepth(nodeToMutate.getDepth()); + parent.setNode(newNode, nodeToMutate); + } else { + AbstractGPNode newNode = (AbstractGPNode)(((AbstractGPNode)this.m_Area[i].getRandomNode().clone())); + newNode.setDepth(nodeToMutate.getDepth()); + newNode.initGrow(this.m_Area[i], this.m_maxAllowedDepth); + parent.setNode(newNode, nodeToMutate); + } + //if (!m_Genotype[i].checkDepth(0) || (m_Genotype[i].isMaxDepthViolated(m_maxAllowedDepth))) { + // System.err.println("Error in GPIndividualProgramData.defaultMutate!"); + //} } } + m_Phenotype=null; // reset pheno } public void defaultInit(InterfaceOptimizationProblem prob) { + m_Phenotype=null; // reset pheno for (int i = 0; i < this.m_Area.length; i++) { if (this.m_Area[i] == null) { EVAERROR.errorMsgOnce("Error in GPIndividualProgramData.defaultInit(): Area["+i+"] == null !!"); @@ -339,9 +358,9 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int * @param b The new init Depth of the GP Tree. */ public void setInitDepth(int b) { - if (b > this.m_maxDepth) { + if (b > this.m_maxAllowedDepth) { System.out.println("Waring Init Depth will be set to Target Depth!"); - b = this.m_maxDepth; + b = this.m_maxAllowedDepth; } this.m_InitDepth = b; } @@ -355,17 +374,29 @@ public class GPIndividualProgramData extends AbstractEAIndividual implements Int /** This method set/get the target depth. * @param b The new target Depth of the GP Tree. */ - public void setMaxDepth(int b) { - this.m_maxDepth = b; + public void setMaxAllowedDepth(int b) { + this.m_maxAllowedDepth = b; } - public int getMaxDepth() { - return this.m_maxDepth; + public int getMaxAllowedDepth() { + return this.m_maxAllowedDepth; } - public String maxDepthTipText() { - return "The maximum depth of the GP tree."; + public String maxAllowedDepthTipText() { + return "The maximum depth allowed for the GP tree."; } public String[] customPropertyOrder() { - return new String[] {"initDepth", "checkMaxDepth", "maxDepth"}; + return new String[] {"initDepth", "checkMaxDepth", "maxAllowedDepth"}; } + + public void updateDepth() { + for (int i=0; i0) { + int k=RNG.randomInt(m_Nodes.length); + return m_Nodes[k].getRandomLeaf(); + } else return this; + } + /** This method allows you to set the parent of the node * @param parent The new parent */ @@ -435,7 +475,8 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial return result; } - /** This method will return the max depth of the tree + /** + * Return the maximal depth of the tree starting here, but relating to the whole tree. * @return The max depth. */ public int getMaxDepth() { @@ -446,6 +487,16 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial return result; } + /** + * Return the depth of the subtree only. + * + * @return + */ + public int getSubtreeDepth() { + int maxDepth = getMaxDepth(); + return maxDepth-m_Depth; + } + /** This method will check if maxdepth is violated * @param maxDepth The max depth. * @return True if MaxDepth is violated @@ -503,4 +554,32 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial return false; } } + + /** + * Update the depth of this node tree starting with the given initial depth of the root. + * + * @param myDepth + */ + public void updateDepth(int myDepth) { + m_Depth=myDepth; + for (int i=0; i1) System.err.println("Warning, crossover may not work on more than one partner! " + this.getClass()); AbstractEAIndividual[] result = null; result = new AbstractEAIndividual[partners.size()+1]; result[0] = (AbstractEAIndividual) (indy1).clone(); for (int i = 0; i < partners.size(); i++) result[i+1] = (AbstractEAIndividual) ((AbstractEAIndividual)partners.get(i)).clone(); - //for (int i = 0; i < result.length; i++) System.out.println("Before Crossover: " +result[i].getSolutionRepresentationFor()); + if (TRACE) for (int i = 0; i < result.length; i++) System.out.println("Before Crossover: " +result[i].getStringRepresentation()); if (partners.size() == 0) return result; if ((indy1 instanceof InterfaceGPIndividual) && (partners.get(0) instanceof InterfaceGPIndividual)) { - - //select node from 0 and memorize parent - ArrayList allNodes = new ArrayList(); + int allowedDepth = ((InterfaceGPIndividual)indy1).getMaxAllowedDepth(); + AbstractGPNode[] nodes = ((InterfaceGPIndividual)result[0]).getPGenotype(); - for (int t = 0; t < nodes.length; t++) { - allNodes = new ArrayList(); - ((InterfaceGPIndividual)result[0]).getPGenotype()[t].addNodesTo(allNodes); - AbstractGPNode oldNode = (AbstractGPNode) allNodes.get(RNG.randomInt(0, allNodes.size()-1)); - AbstractGPNode newNode, memorizingNode = oldNode, tmpNode; - AbstractGPNode oldParent, newParent; - oldParent = oldNode.getParent(); - for (int i = 1; i < result.length; i++) { - // choose Node from i and add it to i-1 - allNodes = new ArrayList(); - ((InterfaceGPIndividual)result[i]).getPGenotype()[t].addNodesTo(allNodes); - newNode = (AbstractGPNode) allNodes.get(RNG.randomInt(0, allNodes.size()-1)); - tmpNode = newNode; - newParent = tmpNode.getParent(); - if (oldParent == null) ((InterfaceGPIndividual)result[i-1]).SetPGenotype(newNode, t); - else oldParent.setNode(newNode, oldNode); - oldNode = tmpNode; - oldParent = newParent; + for (int t = 0; t < nodes.length; t++) { // for each of the genotypes (multiploidy??) + ((InterfaceGPIndividual)result[0]).getPGenotype()[t].getRandomNode(); + AbstractGPNode selNodeThis = ((InterfaceGPIndividual)result[0]).getPGenotype()[t].getRandomNode(); + AbstractGPNode selNodeOther = ((InterfaceGPIndividual)result[1]).getPGenotype()[t].getRandomNode(); + if (maintainMaxDepth) {//System.err.print("."); + int maxTries=10; + // if the echange would violate the depth restriction, choose new nodes for a few times... + while (maxTries>=0 && ((selNodeOther.getSubtreeDepth()+selNodeThis.getDepth()>allowedDepth) || + (selNodeThis.getSubtreeDepth()+selNodeOther.getDepth()>allowedDepth))) { + if (RNG.flipCoin(0.5)) selNodeThis = ((InterfaceGPIndividual)result[0]).getPGenotype()[t].getRandomNode(); + else selNodeOther = ((InterfaceGPIndividual)result[1]).getPGenotype()[t].getRandomNode(); + maxTries--; + } + if (maxTries<0) { // on a failure, at least exchange two leaves, which always works +// System.err.println("Unable to select fitting nodes! Just switch leaves..."); + selNodeThis = ((InterfaceGPIndividual)result[0]).getPGenotype()[t].getRandomLeaf(); + selNodeOther = ((InterfaceGPIndividual)result[1]).getPGenotype()[t].getRandomLeaf(); + } } - // add node from 0 to result.length-1 - if (oldParent == null) { - ((InterfaceGPIndividual)result[result.length-1]).SetPGenotype(memorizingNode, t); - } else { - oldParent.setNode(memorizingNode, oldNode); + if (TRACE) { + System.out.println("Selected t " + selNodeThis.getStringRepresentation()); + System.out.println("Selected o " + selNodeOther.getStringRepresentation()); } + + AbstractGPNode selNodeThisParent, selNodeOtherParent; + selNodeThisParent = selNodeThis.getParent(); + selNodeOtherParent = selNodeOther.getParent(); + + // actually switch individuals! + if (selNodeThisParent == null) ((InterfaceGPIndividual)result[0]).SetPGenotype((AbstractGPNode)selNodeOther.clone(), t); + else selNodeThisParent.setNode((AbstractGPNode)selNodeOther.clone(), selNodeThis); +// for (int i = 0; i < result.length; i++) System.out.println("-- Betw Crossover: " +result[i].getStringRepresentation()); + if (selNodeOtherParent == null) ((InterfaceGPIndividual)result[1]).SetPGenotype((AbstractGPNode)selNodeThis.clone(), t); + else selNodeOtherParent.setNode((AbstractGPNode)selNodeThis.clone(), selNodeOther); + } } //in case the crossover was successfull lets give the mutation operators a chance to mate the strategy parameters - for (int i = 0; i < result.length; i++) result[i].getMutationOperator().crossoverOnStrategyParameters(indy1, partners); - //for (int i = 0; i < result.length; i++) System.out.println("After Crossover: " +result[i].getSolutionRepresentationFor()); + for (int i = 0; i < result.length; i++) { + ((GPIndividualProgramData)result[i]).checkDepth(); + result[i].getMutationOperator().crossoverOnStrategyParameters(indy1, partners); + } + if (TRACE) for (int i = 0; i < result.length; i++) System.out.println("After Crossover: " +result[i].getStringRepresentation()); return result; } diff --git a/src/eva2/server/go/problems/PSymbolicRegression.java b/src/eva2/server/go/problems/PSymbolicRegression.java index 1a284a19..e6d3af6d 100644 --- a/src/eva2/server/go/problems/PSymbolicRegression.java +++ b/src/eva2/server/go/problems/PSymbolicRegression.java @@ -575,7 +575,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements */ public static int getIndySize(AbstractEAIndividual indy) { if (indy instanceof InterfaceDataTypeProgram) { - InterfaceProgram prog = ((InterfaceDataTypeProgram)indy).getProgramData()[0]; + InterfaceProgram prog = ((InterfaceDataTypeProgram)indy).getProgramDataWithoutUpdate()[0]; if (prog instanceof AbstractGPNode) { AbstractGPNode gpNode = (AbstractGPNode)prog; return gpNode.getNumberOfNodes(); @@ -584,7 +584,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements } /** - * Return the depth of an individual representing a program or null + * Return the maximal depth of an individual representing a program or null * if it is of an incompatible type. * * @param indy @@ -592,10 +592,14 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements */ public static int getIndyDepth(AbstractEAIndividual indy) { if (indy instanceof InterfaceDataTypeProgram) { - InterfaceProgram prog = ((InterfaceDataTypeProgram)indy).getProgramData()[0]; + InterfaceProgram prog = ((InterfaceDataTypeProgram)indy).getProgramDataWithoutUpdate()[0]; if (prog instanceof AbstractGPNode) { AbstractGPNode gpNode = (AbstractGPNode)prog; - return gpNode.getMaxDepth(); + int d = gpNode.getMaxDepth(); + //if (!gpNode.checkDepth(0)) { + // System.out.println(d + "\n" + gpNode.getStringRepresentation()); + //} + return d; } else return 0; } else return 0; } diff --git a/src/eva2/server/stat/StatisticsWithGUI.java b/src/eva2/server/stat/StatisticsWithGUI.java index f237b47d..0d25325a 100644 --- a/src/eva2/server/stat/StatisticsWithGUI.java +++ b/src/eva2/server/stat/StatisticsWithGUI.java @@ -242,7 +242,7 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl // plot the column as indicated by the graph description if (currentStatDoubleData[colIndex]!=null) plotFitnessPoint(0, subGraph++, functionCalls, currentStatDoubleData[colIndex]); else { - EVAERROR.errorMsgOnce("Error, data field " + graphDesc.get(i).head + " does not contain primitive data and cannot be plotted."); +// EVAERROR.errorMsgOnce("Error, data field " + graphDesc.get(i).head + " does not contain primitive data and cannot be plotted."); subGraph++; // increase index anyways or the name assignment gets inconsistent } }