From 8ab56480a3a35d8c3b4048fd282aa1439260514b Mon Sep 17 00:00:00 2001 From: Marcel Kronfeld Date: Tue, 29 Jul 2008 09:20:56 +0000 Subject: [PATCH] Merging changes from mk-branch 122:123. --- src/eva2/EvAInfo.java | 6 +- src/eva2/OptimizerRunnable.java | 32 ++++++- .../MutateESMutativeStepSizeControl.java | 2 +- .../go/operators/postprocess/PostProcess.java | 4 +- .../server/go/populations/Population.java | 86 +++++++++++++++---- src/eva2/server/go/problems/F1Problem.java | 1 + src/eva2/server/go/problems/F6Problem.java | 12 +-- .../strategies/ParticleSwarmOptimization.java | 72 +--------------- src/eva2/server/stat/StatisticsDummy.java | 76 ++++++++++++++++ src/eva2/tools/Mathematics.java | 40 +++++++++ src/wsi/ra/math/RNG.java | 2 +- 11 files changed, 236 insertions(+), 97 deletions(-) create mode 100644 src/eva2/server/stat/StatisticsDummy.java diff --git a/src/eva2/EvAInfo.java b/src/eva2/EvAInfo.java index 9fe4fded..9e3bcff6 100644 --- a/src/eva2/EvAInfo.java +++ b/src/eva2/EvAInfo.java @@ -4,8 +4,10 @@ package eva2; * Main product and version information strings. * * --- Changelog + * 2.028: Tuned the Population to sort only when necessary on calls to getBestN... Added StatisticsDummy. + * Slightly tuned SimpleProblemWrapper to call initProblem of simple problems if available. * 2.027: Renamed SetData and SetDataLamarckian from individual datatype interfaces to SetGenotype and SetPhenotype. - * Repaired the GenericArrayEditor. Population measures can now be plottet in stats. + * Repaired the GenericArrayEditor. Population measures can now be plotted in stats. * 2.026: Added DiversityTerminator and KnownOptimaTerminator, slightly changed InterfaceTerminator for these * and InterfaceStatistics to provide termination message to text window. * Killed redundant method getGenerations() in Population. Population.getAllSolutions now returns a @@ -25,7 +27,7 @@ package eva2; public class EvAInfo { public static final String productName = "EvA 2"; public static final String productLongName = "Evolutionary Algorithms Workbench 2"; - public static final String versionNum = new String ("2.027"); + public static final String versionNum = new String ("2.028"); public static final String url = "http://www.ra.cs.uni-tuebingen.de/software/EvA2"; public static final String propertyFile = "resources/EvA2.props"; diff --git a/src/eva2/OptimizerRunnable.java b/src/eva2/OptimizerRunnable.java index 9b38a4ee..a5528fa1 100644 --- a/src/eva2/OptimizerRunnable.java +++ b/src/eva2/OptimizerRunnable.java @@ -16,6 +16,7 @@ import eva2.server.go.populations.Population; import eva2.server.modules.GOParameters; import eva2.server.modules.Processor; import eva2.server.stat.AbstractStatistics; +import eva2.server.stat.StatisticsDummy; import eva2.server.stat.InterfaceTextListener; import eva2.server.stat.StatisticsStandalone; @@ -33,13 +34,42 @@ public class OptimizerRunnable implements Runnable { private boolean postProcessOnly = false; private InterfaceTextListener listener = null; + /** + * Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance without restart, + * meaning that the population will be initialized randomly. + * + * @param params + * @param outputFilePrefix + */ public OptimizerRunnable(GOParameters params, String outputFilePrefix) { this(params, outputFilePrefix, false); } + /** + * This constructor assumes that DummyStatistics are enough. This saves time e.g. for small populations. + * If restart is true, the processor will not reinitialize the population allowing search on predefined populations. + * + * @param params + * @param restart + */ + public OptimizerRunnable(GOParameters params, boolean restart) { + proc = new Processor(new StatisticsDummy(), null, params); + if (proc.getStatistics() instanceof AbstractStatistics) ((AbstractStatistics)proc.getStatistics()).setSaveParams(false); + doRestart = restart; + } + + /** + * Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance with optional restart. + * If restart is true, the processor will not reinitialize the population allowing search on predefined populations. + * The outputFilePrefix may be null. + * + * @param params + * @param outputFilePrefix + * @param restart + */ public OptimizerRunnable(GOParameters params, String outputFilePrefix, boolean restart) { proc = new Processor(new StatisticsStandalone(outputFilePrefix), null, params); - ((AbstractStatistics)proc.getStatistics()).setSaveParams(false); + if (proc.getStatistics() instanceof AbstractStatistics) ((AbstractStatistics)proc.getStatistics()).setSaveParams(false); doRestart = restart; } diff --git a/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java b/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java index fac075dd..b359d2f7 100644 --- a/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java +++ b/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java @@ -96,7 +96,7 @@ public class MutateESMutativeStepSizeControl implements InterfaceMutation, java. if (range[i][1] < x[i]) x[i] = range[i][1]; } ((InterfaceESIndividual)individual).SetDGenotype(x); - System.out.println("new step size: " + m_MutationStepSize); + // System.out.println("new step size: " + m_MutationStepSize); } //System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor()); } diff --git a/src/eva2/server/go/operators/postprocess/PostProcess.java b/src/eva2/server/go/operators/postprocess/PostProcess.java index abdeaf66..dfdc1614 100644 --- a/src/eva2/server/go/operators/postprocess/PostProcess.java +++ b/src/eva2/server/go/operators/postprocess/PostProcess.java @@ -22,6 +22,7 @@ import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.InterfaceMultimodalProblemKnown; import eva2.server.go.strategies.HillClimbing; import eva2.server.stat.InterfaceTextListener; +import eva2.server.stat.StatsParameter; import eva2.tools.Pair; @@ -371,8 +372,9 @@ public class PostProcess { } hc.setPopulation(pop); // hc.initByPopulation(pop, false); - hcRunnable = new OptimizerRunnable(OptimizerFactory.makeParams(hc, pop, problem, 0, term), null, true); + hcRunnable = new OptimizerRunnable(OptimizerFactory.makeParams(hc, pop, problem, 0, term), true); hcRunnable.getGOParams().setDoPostProcessing(false); + hcRunnable.setVerbosityLevel(StatsParameter.VERBOSITY_NONE); hcRunnable.run(); hcRunnable.getGOParams().setDoPostProcessing(true); hcRunnable = null; diff --git a/src/eva2/server/go/populations/Population.java b/src/eva2/server/go/populations/Population.java index b0456bdd..e4d041d4 100644 --- a/src/eva2/server/go/populations/Population.java +++ b/src/eva2/server/go/populations/Population.java @@ -34,6 +34,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea protected int m_FunctionCalls = 0; protected int m_Size = 50; protected Population m_Archive = null; + transient private ArrayList sortedArr = null; + private int lastQModCount = -1; transient protected InterfacePopulationChangedEventListener m_Listener = null; protected int notifyEvalInterval = 0; protected HashMap additionalPopData = null; @@ -161,7 +163,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea useHistory = useHist; } - /** This method will allow cou to increment the current number of function calls. + /** This method will allow you to increment the current number of function calls. */ public void incrFunctionCalls() { this.m_FunctionCalls++; @@ -178,17 +180,23 @@ public class Population extends ArrayList implements PopulationInterface, Clonea */ public void incrFunctionCallsby(int d) { if (doEvalNotify()) { - System.out.println("checking funcall event..."); - int nextStep = ((m_FunctionCalls/notifyEvalInterval)+1) * notifyEvalInterval; // next interval boundary - if (nextStep <= (m_FunctionCalls+d)) { +// System.out.println("checking funcall event..."); + int nextStep; // next interval boundary + while ((nextStep = calcNextBoundary()) <= (m_FunctionCalls+d)) { // the notify interval will be stepped over or hit int toHit = (nextStep - m_FunctionCalls); this.m_FunctionCalls += toHit; // little cheat, notify may be after some more evals firePropertyChangedEvent(funCallIntervalReached); - this.m_FunctionCalls += (d-toHit); + d = d-toHit; +// this.m_FunctionCalls += (d-toHit); } + if (d>0) this.m_FunctionCalls += d; // add up the rest } else this.m_FunctionCalls += d; } + + private int calcNextBoundary() { + return ((m_FunctionCalls/notifyEvalInterval)+1) * notifyEvalInterval; + } /** Something has changed */ @@ -363,32 +371,69 @@ public class Population extends ArrayList implements PopulationInterface, Clonea } /** - * This method returns the n current best individuals from the population, where + * This method returns the n currently best individuals from the population, where * the sorting criterion is delivered by an AbstractEAIndividualComparator. * There are less than n individuals returned if the population is smaller than n. - * If n is <= 0, then all individuals are returned and effectively just sorted - * by fitness. + * The comparator does not check constraints! * * @param n number of individuals to look out for * @return The m best individuals, where m <= n * */ public Population getBestNIndividuals(int n) { - if (n <= 0) n = super.size(); + return getSortedNIndividuals(n, true); + } + + /** + * This method returns the n current best individuals from the population, where + * the sorting criterion is delivered by an AbstractEAIndividualComparator. + * There are less than n individuals returned if the population is smaller than n. + * The comparator does not check constraints! + * + * @param n number of individuals to look out for + * @param bBestOrWorst if true, the best n are returned, else the worst n individuals + * @return The m sorted best or worst individuals, where m <= n + * + */ + public Population getSortedNIndividuals(int n, boolean bBestOrWorst) { + if ((n < 0) || (n>super.size())) { + System.err.println("invalid request to getSortedNIndividuals: n="+n + ", size is " + super.size()); + n = super.size(); + } + int skip = 0; + if (!bBestOrWorst) skip = super.size()-n; + Population result = new Population(n); - PriorityQueue queue = new PriorityQueue(super.size(), new AbstractEAIndividualComparator()); + ArrayList sorted = getSorted(); - for (int i = 0; i < super.size(); i++) { - queue.add(getEAIndividual(i)); - } - for (int i = 0; i getSorted() { + if (sortedArr == null || (super.modCount != lastQModCount)) { + PriorityQueue sQueue = new PriorityQueue(super.size(), new AbstractEAIndividualComparator()); + for (int i = 0; i < super.size(); i++) { + sQueue.add(getEAIndividual(i)); + } + lastQModCount = super.modCount; + if (sortedArr==null) sortedArr = new ArrayList(this.size()); + else sortedArr.clear(); + AbstractEAIndividual indy; + while ((indy=sQueue.poll())!=null) sortedArr.add(indy); + } + return sortedArr; + } + /** This method returns n random best individuals from the population. * * @param n number of individuals to look out for @@ -662,6 +707,15 @@ public class Population extends ArrayList implements PopulationInterface, Clonea return addIndividual((IndividualInterface)o); } + /** + * ArrayList does not increase the modCount in set. Why??? + */ + public Object set(int index, Object element) { + Object prev = super.set(index, element); + modCount++; + return prev; + } + public boolean addIndividual(IndividualInterface ind) { super.add(ind); return true; diff --git a/src/eva2/server/go/problems/F1Problem.java b/src/eva2/server/go/problems/F1Problem.java index e2820957..6da2653c 100644 --- a/src/eva2/server/go/problems/F1Problem.java +++ b/src/eva2/server/go/problems/F1Problem.java @@ -50,6 +50,7 @@ public class F1Problem extends AbstractProblemDouble implements Interface2DBorde */ public void initProblem() { // this.m_OverallBest = null; + initTemplate(); } protected double[] getEvalArray(AbstractEAIndividual individual){ diff --git a/src/eva2/server/go/problems/F6Problem.java b/src/eva2/server/go/problems/F6Problem.java index f528081e..9823ed51 100644 --- a/src/eva2/server/go/problems/F6Problem.java +++ b/src/eva2/server/go/problems/F6Problem.java @@ -1,7 +1,7 @@ package eva2.server.go.problems; import eva2.server.go.individuals.ESIndividualDoubleData; -import eva2.server.go.strategies.ParticleSwarmOptimization; +import eva2.tools.Mathematics; import wsi.ra.math.Jama.Matrix; /** @@ -32,10 +32,12 @@ public class F6Problem extends F1Problem implements InterfaceMultimodalProblem, */ public void initProblem() { super.initProblem(); - rotation = new Matrix(m_ProblemDimension, m_ProblemDimension); - Matrix vec = new Matrix(m_ProblemDimension, 1); - for (int i=0; i