From 52d707f0e0c63259f9ac25d0207d9354ff92274b Mon Sep 17 00:00:00 2001 From: Marcel Kronfeld Date: Mon, 15 Jun 2009 13:21:10 +0000 Subject: [PATCH] MK branch revs. 263 & 295: GUI reordering, GP bugfix. Plus minors (JEInterface.m, tex2html) --- .../@JEInterface/JEInterface.m | 6 +- src/eva2/gui/GenericObjectEditor.java | 23 +- src/eva2/gui/PropertySheetPanel.java | 228 ++++++++++++------ .../codings/gp/AbstractGPNode.java | 25 +- .../go/individuals/codings/gp/GPArea.java | 36 +-- .../go/problems/PSymbolicRegression.java | 24 +- .../go/strategies/EvolutionStrategies.java | 60 +++-- src/eva2/server/modules/Processor.java | 2 +- src/eva2/tools/Mathematics.java | 8 + 9 files changed, 284 insertions(+), 128 deletions(-) diff --git a/resources/MatlabInterface/@JEInterface/JEInterface.m b/resources/MatlabInterface/@JEInterface/JEInterface.m index e44c8e95..9b955694 100644 --- a/resources/MatlabInterface/@JEInterface/JEInterface.m +++ b/resources/MatlabInterface/@JEInterface/JEInterface.m @@ -1,8 +1,8 @@ function int = JEInterface(fhandle, range, varargin) % EvA2 Interface for Matlab -% JEInterface(interfaceName, fhandle, range) -% JEInterface(interfaceName, fhandle, range, defaultargs) -% JEInterface(interfaceName, fhandle, range, defaultargs, options...) +% JEInterface(fhandle, range) +% JEInterface(fhandle, range, defaultargs) +% JEInterface(fhandle, range, defaultargs, options...) % % Arguments: % fhandle: a function handle defining the optimization target. diff --git a/src/eva2/gui/GenericObjectEditor.java b/src/eva2/gui/GenericObjectEditor.java index 9b22e74e..e5bf8204 100644 --- a/src/eva2/gui/GenericObjectEditor.java +++ b/src/eva2/gui/GenericObjectEditor.java @@ -583,7 +583,7 @@ public class GenericObjectEditor implements PropertyEditor { } return true; } catch (Exception e) { - System.err.println("exception in setHideProperty: " + e.getMessage()); + System.err.println("exception in setHideProperty for " + cls.getName() + "/" + property + " : " + e.getMessage()); return false; } } @@ -616,11 +616,30 @@ public class GenericObjectEditor implements PropertyEditor { System.err.println("Error: property " + property + " not found!"); return false; } catch (Exception e) { - System.err.println("exception in setHideProperty: " + e.getMessage()); + System.err.println("exception in setHideProperty for " + cls.getName() + "/" + property + " : " + e.getMessage()); return false; } } + /** + * Hide or unhide all properties of a given class. Added to avoid the problem with hidden + * properties of inherited classes hide the property for all classes within the same inheritance tree. + * + * @param cls + * @param hide + */ + public static void setHideAllProperties(Class cls, boolean hide) { + try { + BeanInfo bi = Introspector.getBeanInfo(cls); + PropertyDescriptor[] props = bi.getPropertyDescriptors(); + for (int i=0; i1) System.err.println("String has ambiguous prefix: " + str + " -- " + BeanInspector.toString(matchSet)); else { // exactly one match: AbstractGPNode currentNode = (AbstractGPNode)matchSet.get(0).clone(); -// System.out.println("Found match: " + currentNode.getOpIdentifier() + "/" + currentNode.getArity()); + if (TRACE) System.out.println("Found match: " + currentNode.getOpIdentifier() + "/" + currentNode.getArity()); int cutFront=currentNode.getOpIdentifier().length(); String restStr; if (currentNode.getArity()==0) { @@ -130,7 +131,7 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial currentNode.m_Nodes[i]=nextState.head(); restStr=nextState.tail().substring(1).trim(); // cut comma or brace } -// System.out.println("lacking rest: " + restStr); + if (TRACE) System.out.println("read " + currentNode.getName() + ", rest: " + restStr); return new Pair(currentNode, restStr); } } @@ -145,7 +146,8 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial int firstBrace = str.indexOf(')'); if ((firstBrace >= 0) && (firstBrace0) firstArg=str.substring(0,argLen); + else firstArg=str.trim(); try { Double d=Double.parseDouble(firstArg); return new Pair(d, str.substring(firstArg.length())); @@ -183,8 +185,10 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial Vector nodeTypes, String str, boolean firstLongestOnly, boolean ignoreCase) { Vector matching = new Vector(); for (int i=0; i0) reqPrefix+="("; + if (str.startsWith(reqPrefix)) matching.add(nodeTypes.get(i)); + else if (ignoreCase && str.toLowerCase().startsWith(reqPrefix.toLowerCase())) matching.add(nodeTypes.get(i)); } if (matching.size()>1 && firstLongestOnly) { // allow only the longest match (or first longest) int maxLen = matching.get(0).getOpIdentifier().length(); @@ -209,8 +213,13 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial public static void main(String[] args) { // Double d = Double.parseDouble("2.58923 + 3"); - AbstractGPNode node = AbstractGPNode.parseFromString("+(x,cOs(*(pI,x1)))"); -// System.out.println("Parsed GPNode: " + node.getStringRepresentation()); +// AbstractGPNode node = AbstractGPNode.parseFromString("-23421"); + AbstractGPNode node = AbstractGPNode.parseFromString("+(-23421,cOs(*(pI,x1)))"); + AbstractGPNode.parseFromString("+(+(85.334407,*(0.0056858,*(x1,x4))), +(*(0.00026,*(x0,x3)),*(-0.0022053,*(x2,x4))))"); + AbstractGPNode.parseFromString("+(+(80.51249,*(0.0071317,*(x1,x4))), +(*(0.0029955,*(x0,x1)),*(0.0021813,*(x2,x2))))"); + AbstractGPNode.parseFromString("+(+(9.300961,*(0.0047026,*(x2,x4))), +(*(0.0012547,*(x0,x2)),*(0.0019085,*(x2,x3))))"); + + System.out.println("Parsed GPNode: " + node.getStringRepresentation()); node = AbstractGPNode.parseFromString(node.getStringRepresentation()); } diff --git a/src/eva2/server/go/individuals/codings/gp/GPArea.java b/src/eva2/server/go/individuals/codings/gp/GPArea.java index 0e543e11..0c8855bf 100644 --- a/src/eva2/server/go/individuals/codings/gp/GPArea.java +++ b/src/eva2/server/go/individuals/codings/gp/GPArea.java @@ -19,9 +19,9 @@ public class GPArea implements java.io.Serializable { /** Handles property change notification */ private transient PropertyChangeSupport m_Support = new PropertyChangeSupport(this); - private ArrayList m_CompleteList = new ArrayList(); - private ArrayList m_ReducedList = new ArrayList(); - private ArrayList m_BlackList = new ArrayList(); + private ArrayList m_CompleteList = new ArrayList(); + private ArrayList m_ReducedList = new ArrayList(); + private ArrayList m_BlackList = new ArrayList(); public GPArea() { @@ -29,11 +29,11 @@ public class GPArea implements java.io.Serializable { public GPArea(GPArea g) { if (g.m_BlackList != null) - this.m_BlackList = (ArrayList)g.m_BlackList.clone(); + this.m_BlackList = (ArrayList)g.m_BlackList.clone(); if (g.m_ReducedList != null) - this.m_ReducedList = (ArrayList)g.m_ReducedList.clone(); + this.m_ReducedList = (ArrayList)g.m_ReducedList.clone(); if (g.m_CompleteList != null) - this.m_CompleteList = (ArrayList)g.m_CompleteList.clone(); + this.m_CompleteList = (ArrayList)g.m_CompleteList.clone(); } public Object clone() { @@ -60,13 +60,13 @@ public class GPArea implements java.io.Serializable { /** This method allows you to fetch the black list * @return blacklist */ - public ArrayList getBlackList() { + public ArrayList getBlackList() { return this.m_BlackList; } /** This method allows you to set the black list * @param a blacklist */ - public void SetBlackList(ArrayList a) { + public void SetBlackList(ArrayList a) { this.m_BlackList = a; } /** This method allows you to set a BlackList element @@ -80,21 +80,21 @@ public class GPArea implements java.io.Serializable { /** This method allows you to fetch the CompleteList * @return blacklist */ - public ArrayList getCompleteList() { + public ArrayList getCompleteList() { return this.m_CompleteList; } /** This method allows you to fetch the CompleteList * @return blacklist */ - public ArrayList getReducedList() { + public ArrayList getReducedList() { return this.m_ReducedList; } /** This method allows you to set the CompleteList * @param a blacklist */ - public void SetCompleteList(ArrayList a) { + public void SetCompleteList(ArrayList a) { this.m_CompleteList = a; m_Support.firePropertyChange("GPArea", null, this); } @@ -102,7 +102,7 @@ public class GPArea implements java.io.Serializable { /** This method compiles the Complete List to the allowed list using the BlackList */ public void compileReducedList() { - this.m_ReducedList = new ArrayList(); + this.m_ReducedList = new ArrayList(); for (int i = 0; i < this.m_CompleteList.size(); i++) { if (((Boolean)(this.m_BlackList.get(i))).booleanValue()) { this.m_ReducedList.add(this.m_CompleteList.get(i)); @@ -115,7 +115,7 @@ public class GPArea implements java.io.Serializable { * @param targetarity The target arity. */ public AbstractGPNode getRandomNodeWithArity(int targetarity) { - ArrayList tmpArray = new ArrayList(); + ArrayList tmpArray = new ArrayList(); for (int i = 0; i < this.m_ReducedList.size(); i++) { if (((AbstractGPNode)this.m_ReducedList.get(i)).getArity() == targetarity) tmpArray.add(this.m_ReducedList.get(i)); } @@ -133,7 +133,7 @@ public class GPArea implements java.io.Serializable { /** This method will return a non terminal */ public AbstractGPNode getRandomNonTerminal() { - ArrayList tmpArray = new ArrayList(); + ArrayList tmpArray = new ArrayList(); for (int i = 0; i < this.m_ReducedList.size(); i++) { if (((AbstractGPNode)this.m_ReducedList.get(i)).getArity() > 0) tmpArray.add(this.m_ReducedList.get(i)); } @@ -146,19 +146,21 @@ public class GPArea implements java.io.Serializable { } public void clear() { - m_CompleteList = new ArrayList(); - m_ReducedList = new ArrayList(); - m_BlackList = new ArrayList(); + m_CompleteList = new ArrayList(); + m_ReducedList = new ArrayList(); + m_BlackList = new ArrayList(); m_Support.firePropertyChange("GPArea", null, this); } public void addPropertyChangeListener(PropertyChangeListener l) { + if (m_Support==null) m_Support = new PropertyChangeSupport(this); m_Support.addPropertyChangeListener(l); } /** * */ public void removePropertyChangeListener(PropertyChangeListener l) { + if (m_Support==null) m_Support = new PropertyChangeSupport(this); m_Support.removePropertyChangeListener(l); } } diff --git a/src/eva2/server/go/problems/PSymbolicRegression.java b/src/eva2/server/go/problems/PSymbolicRegression.java index 197bce00..47edbaa1 100644 --- a/src/eva2/server/go/problems/PSymbolicRegression.java +++ b/src/eva2/server/go/problems/PSymbolicRegression.java @@ -44,7 +44,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements private double[] m_C = new double[m_NumberOfConstants]; private boolean m_UseInnerConst = false; private boolean m_UseLocalHillClimbing = false; - transient private GPArea m_GPArea = new GPArea(); + private GPArea m_GPArea = new GPArea(); protected AbstractEAIndividual m_OverallBest = null; protected double m_Noise = 0.0; @@ -55,6 +55,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements public PSymbolicRegression() { this.m_Template = new GPIndividualProgramData(); this.initProblem(); + this.compileArea(); } public PSymbolicRegression(PSymbolicRegression b) { @@ -100,17 +101,16 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements this.m_OverallBest = null; this.m_C = new double[this.m_NumberOfConstants]; for (int i = 0; i < this.m_C.length; i++) this.m_C[i] = RNG.randomDouble(-10, 10); - this.compileArea(); } /** - * This method compiles the area + * This method compiles the area. Only to be called once in the constructor + * to build the basic function set or if the number of constants etc. change. */ private void compileArea() { // unfortunately this must be cloned or the GUI wont update. -// if (m_GPArea==null) - m_GPArea = new GPArea(); -// else m_GPArea = (GPArea)m_GPArea.clone(); + GPArea oldArea=m_GPArea; + m_GPArea = new GPArea(); if (m_GPArea.isEmpty()) { this.m_GPArea.add2CompleteList(new GPNodeAdd()); @@ -126,6 +126,9 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements for (int i = 0; i < this.m_X.length; i++) this.m_GPArea.add2CompleteList(new GPNodeInput("X"+i)); for (int i = 0; i < this.m_C.length; i++) this.m_GPArea.add2CompleteList(new GPNodeInput("C"+i)); } + if ((oldArea!=null) && (oldArea.getBlackList()!=null) && (oldArea.getBlackList().size()==m_GPArea.getBlackList().size())) { + m_GPArea.SetBlackList(oldArea.getBlackList()); + } this.m_GPArea.compileReducedList(); } @@ -319,7 +322,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements * @return description */ public String globalInfo() { - return "The task is to infer the equation from a system that can only be observed"; + return "The task is to infer the equation of a system that can only be observed at a number of checkpoints."; } /** This method allows you to choose how much noise is to be added to the @@ -360,7 +363,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements return this.m_UseLocalHillClimbing; } public String useLocalHillClimbingTipText() { - return "Toggel the use of local hill climbing for inner constants."; + return "Toggle the use of local hill climbing for inner constants."; } /** This method allows you to set the number of ephremial constants. @@ -368,8 +371,9 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements */ public void setNumberOfConstants(int b) { this.m_NumberOfConstants = b; - m_GPArea.clear(); this.initProblem(); + m_GPArea.clear(); + this.compileArea(); } public int getNumberOfConstants() { return this.m_NumberOfConstants; @@ -407,7 +411,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements return this.m_GPArea; } public String areaTipText() { - return "Select elements from the available area."; + return "Select function set from the available area."; } /** This method allows you to toggle path visualisation on and off. diff --git a/src/eva2/server/go/strategies/EvolutionStrategies.java b/src/eva2/server/go/strategies/EvolutionStrategies.java index 9bb47824..8fa8a336 100644 --- a/src/eva2/server/go/strategies/EvolutionStrategies.java +++ b/src/eva2/server/go/strategies/EvolutionStrategies.java @@ -150,20 +150,11 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ */ protected Population generateEvalChildren(Population fromPopulation) { Population result = m_Population.cloneWithoutInds(), parents; - AbstractEAIndividual[] offSprings; - AbstractEAIndividual tmpIndy; result.clear(); - this.m_ParentSelection.prepareSelection(fromPopulation); - this.m_PartnerSelection.prepareSelection(fromPopulation); - parents = this.m_ParentSelection.selectFrom(fromPopulation, this.m_Lambda); - for (int i = 0; i < parents.size(); i++) { - tmpIndy = (AbstractEAIndividual)parents.get(i); - offSprings = tmpIndy.mateWith(this.m_PartnerSelection.findPartnerFor(tmpIndy, fromPopulation, this.m_NumberOfPartners)); - offSprings[0].mutate(); - result.add(i, offSprings[0]); - } + parents = generateChildren(fromPopulation, result, this.m_Lambda); + this.evaluatePopulation(result); if (result.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) { @@ -174,13 +165,43 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ return result; } - - protected Population selectParents() { - this.m_EnvironmentSelection.prepareSelection(this.m_Population); - return this.m_EnvironmentSelection.selectFrom(this.m_Population, this.m_Mu); + + /** + * Create a new population by parent selection, partner selection, recombination and crossover. + * The new population is added to the result population, while the selected parent population (after + * selection but before recombination/crossover) is returned. + * Returned parents and result population are to have the same size and correspond per individual. + * + * @param fromPopulation + * @param result + * @param lambda + * @return + */ + protected Population generateChildren(Population fromPopulation, Population result, int lambda) { + AbstractEAIndividual tmpIndy; + AbstractEAIndividual[] offSprings; + Population parents; + + this.m_ParentSelection.prepareSelection(fromPopulation); + this.m_PartnerSelection.prepareSelection(fromPopulation); + parents = this.m_ParentSelection.selectFrom(fromPopulation, lambda); + + for (int i = 0; i < parents.size(); i++) { + tmpIndy = (AbstractEAIndividual)parents.get(i); + offSprings = tmpIndy.mateWith(this.m_PartnerSelection.findPartnerFor(tmpIndy, fromPopulation, this.m_NumberOfPartners)); + offSprings[0].mutate(); + result.add(i, offSprings[0]); + } + return parents; } - /** The optimize method will compute a 'improved' and evaluated population + protected Population selectParents(Population fromPop, int mu) { + this.m_EnvironmentSelection.prepareSelection(fromPop); + return this.m_EnvironmentSelection.selectFrom(fromPop, mu); + } + + /** + * The optimize method will compute an improved and evaluated population. */ public void optimize() { Population nextGeneration, parents; @@ -188,7 +209,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ //System.out.println("optimize"); // first perform the environment selection to select myu parents - parents = selectParents(); + parents = selectParents(m_Population, this.m_Mu); // System.out.println("-- selected avg fit " + BeanInspector.toString(parents.getMeanFitness()) + " from last gen " + BeanInspector.toString(m_Population.getMeanFitness())); @@ -370,6 +391,11 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ public String globalInfo() { return "This is an Evolution Strategy. Note that the population size depends on mu (number of parents) and lambda (number of offspring)."; } + + public String[] customPropertyOrder() { + return new String[]{"mu", "lambda"}; + } + /** This method will return a naming String * @return The name of the algorithm */ diff --git a/src/eva2/server/modules/Processor.java b/src/eva2/server/modules/Processor.java index 073814ca..36f980e1 100644 --- a/src/eva2/server/modules/Processor.java +++ b/src/eva2/server/modules/Processor.java @@ -282,7 +282,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo * @return the percentage of current (multi-)run already performed */ private int getStatusPercent(Population pop, int currentRun, int multiRuns) { - double percentPerRun = 100/multiRuns; + double percentPerRun = 100./multiRuns; int curProgress; if (this.goParams.getTerminator() instanceof EvaluationTerminator) { double curRunPerf = pop.getFunctionCalls()*percentPerRun/(double)((EvaluationTerminator)this.goParams.getTerminator()).getFitnessCalls(); diff --git a/src/eva2/tools/Mathematics.java b/src/eva2/tools/Mathematics.java index 4bb279ed..ef1854d7 100644 --- a/src/eva2/tools/Mathematics.java +++ b/src/eva2/tools/Mathematics.java @@ -25,6 +25,14 @@ public class Mathematics { System.out.println(median(y) / 1000); } + public static void revertArray(Object[] src, Object[] dst) { + if (dst.length>=src.length) { + for (int i=0; i