From 1baa61018eb63f79541ce9e443e1abc3009e91bf Mon Sep 17 00:00:00 2001 From: Marcel Kronfeld Date: Tue, 24 Jun 2008 14:39:56 +0000 Subject: [PATCH] Check EvAInfo for change log. --- src/eva2/EvAInfo.java | 11 +- src/eva2/OptimizerRunnable.java | 2 +- src/eva2/server/go/InterfaceTerminator.java | 39 +++-- .../ESIndividualPermutationData.java | 16 +- .../distancemetric/GenotypeMetricBitSet.java | 6 +- .../distancemetric/ObjectiveSpaceMetric.java | 2 +- .../distancemetric/PhenotypeMetric.java | 20 +-- .../SigmaSingleMetricGlobalMutation.java | 2 +- .../MutateESMutativeStepSizeControl.java | 38 ++++- .../go/operators/postprocess/PostProcess.java | 44 ++++-- .../terminators/CombinedTerminator.java | 43 +++--- .../terminators/DiversityTerminator.java | 143 ++++++++++++++++++ .../terminators/EvaluationTerminator.java | 138 ++++++++--------- .../FitnessConvergenceTerminator.java | 19 ++- .../terminators/FitnessValueTerminator.java | 22 ++- .../terminators/GenerationTerminator.java | 125 ++++++++------- .../KnownOptimaFoundTerminator.java | 85 +++++++++++ .../PhenotypeConvergenceTerminator.java | 15 +- .../go/populations/InterfaceSolutionSet.java | 16 ++ .../server/go/populations/Population.java | 23 ++- .../server/go/populations/SolutionSet.java | 34 +++++ .../server/go/problems/MatlabProblem.java | 2 +- .../CHCAdaptiveSearchAlgorithm.java | 9 +- .../go/strategies/ClusterBasedNichingEA.java | 13 +- .../go/strategies/ClusteringHillClimbing.java | 9 +- .../go/strategies/DifferentialEvolution.java | 7 +- .../go/strategies/EvolutionStrategies.java | 6 +- .../strategies/EvolutionaryProgramming.java | 6 +- .../server/go/strategies/FloodAlgorithm.java | 6 +- .../go/strategies/GeneticAlgorithm.java | 6 +- .../strategies/GradientDescentAlgorithm.java | 6 +- .../server/go/strategies/HillClimbing.java | 6 +- .../go/strategies/InterfaceOptimizer.java | 14 +- .../server/go/strategies/IslandModelEA.java | 7 +- .../go/strategies/MemeticAlgorithm.java | 6 +- .../go/strategies/MonteCarloSearch.java | 6 +- .../go/strategies/MultiObjectiveEA.java | 6 +- .../MultiObjectiveMemeticAlgorithmII.java | 6 +- .../ParticleFilterOptimization.java | 6 +- .../strategies/ParticleSwarmOptimization.java | 6 +- .../PopulationBasedIncrementalLearning.java | 6 +- .../go/strategies/SimulatedAnnealing.java | 6 +- .../server/go/strategies/SteadyStateGA.java | 6 +- .../go/strategies/ThresholdAlgorithm.java | 6 +- src/eva2/server/go/strategies/Tribes.java | 10 +- .../go/strategies/WingedMultiObjectiveEA.java | 6 +- src/eva2/server/modules/Processor.java | 21 +-- src/eva2/server/stat/AbstractStatistics.java | 4 +- src/eva2/server/stat/InterfaceStatistics.java | 2 +- .../server/stat/StatisticsStandalone.java | 4 +- src/eva2/server/stat/StatisticsWithGUI.java | 4 +- src/wsi/ra/math/RNG.java | 23 +++ 52 files changed, 757 insertions(+), 317 deletions(-) create mode 100644 src/eva2/server/go/operators/terminators/DiversityTerminator.java create mode 100644 src/eva2/server/go/operators/terminators/KnownOptimaFoundTerminator.java create mode 100644 src/eva2/server/go/populations/InterfaceSolutionSet.java create mode 100644 src/eva2/server/go/populations/SolutionSet.java diff --git a/src/eva2/EvAInfo.java b/src/eva2/EvAInfo.java index 85107996..ca6d5429 100644 --- a/src/eva2/EvAInfo.java +++ b/src/eva2/EvAInfo.java @@ -3,19 +3,28 @@ package eva2; /** * Main product and version information strings. * + * --- Changelog + * + * 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 + * SolutionSet combining last population with a set of possibly archived solutions. + * Post processing with HC may now use variable step size mutation. * 2.025: FunctionArea may now plot circles easily. The FLensProblemViewer seems to be cured. * 2.024: Cleaned up AbstractGOParams, deactivated parent logging (saving memory) * 2.023: Cleaned up the PF strategy * 2.022: Some changes to the SimpleProblemWrapper, not of great interest. However, * simple problems may now access a plot quite easily. * + * --- End Changelog + * * @author mkron * */ 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.025"); + public static final String versionNum = new String ("2.026"); 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 becd2ec0..9b38a4ee 100644 --- a/src/eva2/OptimizerRunnable.java +++ b/src/eva2/OptimizerRunnable.java @@ -118,7 +118,7 @@ public class OptimizerRunnable implements Runnable { return "Post processing finished"; } else { InterfaceTerminator term = proc.getGOParams().getTerminator(); - return term.terminatedBecause(proc.getGOParams().getOptimizer().getPopulation()); + return term.lastTerminationMessage(); } } else return "Not yet terminated"; } diff --git a/src/eva2/server/go/InterfaceTerminator.java b/src/eva2/server/go/InterfaceTerminator.java index 1833499b..d10793b9 100644 --- a/src/eva2/server/go/InterfaceTerminator.java +++ b/src/eva2/server/go/InterfaceTerminator.java @@ -1,26 +1,25 @@ package eva2.server.go; -/* - * Title: EvA2 - * Description: - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Holger Ulmer, Felix Streichert, Hannes Planatscher - * @version: $Revision: 306 $ - * $Date: 2007-12-04 14:22:52 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ - */ -/*==========================================================================* - * IMPORTS - *==========================================================================*/ -/*==========================================================================* -* INTERFACE DECLARATION -*==========================================================================*/ + +import eva2.server.go.populations.InterfaceSolutionSet; +import eva2.server.go.problems.InterfaceOptimizationProblem; + /** + * Interface for a termination criterion. + * + * @author mkron, streiche * */ public interface InterfaceTerminator { - public boolean isTerminated(PopulationInterface pop); - public String toString(); - public String terminatedBecause(PopulationInterface pop); - public void init(); + /** + * Test a given population for convergence with the criterion defined by the instance. + * + * @param pop the population to test + * @return true if the population fulfills the termination criterion, else false + */ + public boolean isTerminated(PopulationInterface pop); + public boolean isTerminated(InterfaceSolutionSet pop); + + public String toString(); + public String lastTerminationMessage(); + public void init(InterfaceOptimizationProblem prob); } \ No newline at end of file diff --git a/src/eva2/server/go/individuals/ESIndividualPermutationData.java b/src/eva2/server/go/individuals/ESIndividualPermutationData.java index b3b72068..52736948 100644 --- a/src/eva2/server/go/individuals/ESIndividualPermutationData.java +++ b/src/eva2/server/go/individuals/ESIndividualPermutationData.java @@ -50,14 +50,14 @@ public class ESIndividualPermutationData extends AbstractEAIndividual implements for (int i = 0; i < this.m_Genotype.length; i++) { // if (individual.m_Phenotype != null) { - this.m_Genotype[i] = new double[individual.m_Genotype[i].length]; - this.m_Range[i] = new double[individual.m_Genotype[i].length][2]; - for (int j = 0; j < this.m_Genotype[i].length; j++) { - this.m_Genotype[i][j] = individual.m_Genotype[i][j]; - this.m_Range[i][j][0] = individual.m_Range[i][j][0]; - this.m_Range[i][j][1] = individual.m_Range[i][j][1]; - // } - } + this.m_Genotype[i] = new double[individual.m_Genotype[i].length]; + this.m_Range[i] = new double[individual.m_Genotype[i].length][2]; + for (int j = 0; j < this.m_Genotype[i].length; j++) { + this.m_Genotype[i][j] = individual.m_Genotype[i][j]; + this.m_Range[i][j][0] = individual.m_Range[i][j][0]; + this.m_Range[i][j][1] = individual.m_Range[i][j][1]; + // } + } } // cloning the members of AbstractEAIndividual diff --git a/src/eva2/server/go/operators/distancemetric/GenotypeMetricBitSet.java b/src/eva2/server/go/operators/distancemetric/GenotypeMetricBitSet.java index df8ce62f..964e1f78 100644 --- a/src/eva2/server/go/operators/distancemetric/GenotypeMetricBitSet.java +++ b/src/eva2/server/go/operators/distancemetric/GenotypeMetricBitSet.java @@ -46,9 +46,9 @@ public class GenotypeMetricBitSet implements InterfaceDistanceMetric, java.io.Se for (int i = 0; i < length; i++) { if (dIndy1.get(i) == dIndy2.get(i)) result += 0; - else result += 1/(double)length; + else result += 1; } - return result; + return result/(double)length; } /********************************************************************************************************************** * These are for GUI @@ -57,7 +57,7 @@ public class GenotypeMetricBitSet implements InterfaceDistanceMetric, java.io.Se * @return description */ public String globalInfo() { - return "This is a genotype based distance metric suited for binary data. Metric is computed on a normalized search space."; + return "This is a genotype based distance metric suited for binary data. The hamming distance is computed and normalized by chromosome length."; } /** This method will return a naming String * @return The name of the algorithm diff --git a/src/eva2/server/go/operators/distancemetric/ObjectiveSpaceMetric.java b/src/eva2/server/go/operators/distancemetric/ObjectiveSpaceMetric.java index 13cb935f..894e83d7 100644 --- a/src/eva2/server/go/operators/distancemetric/ObjectiveSpaceMetric.java +++ b/src/eva2/server/go/operators/distancemetric/ObjectiveSpaceMetric.java @@ -48,7 +48,7 @@ public class ObjectiveSpaceMetric implements InterfaceDistanceMetric, java.io.Se * @return description */ public String globalInfo() { - return "This is a objective space based metric."; + return "The objective space metric calculates euclidian distances on the fitness vectors."; } /** This method will return a naming String * @return The name of the algorithm diff --git a/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java b/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java index ab19f713..7a7078a9 100644 --- a/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java +++ b/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java @@ -23,6 +23,7 @@ import eva2.server.go.individuals.codings.gp.InterfaceProgram; */ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Serializable { private static PhenotypeMetric pMetric = null; + private static GenotypeMetricBitSet bitMetric = null; public PhenotypeMetric() { } @@ -79,7 +80,8 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali return d[n][m]; } - /** This method allows you to compute the distance between two individuals. + /** + * This method allows you to compute the distance between two individuals. * Depending on the metric this method may reject some types of individuals. * The default return value would be 1.0. * @param indy1 The first individual. @@ -88,18 +90,10 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali */ public double distance(AbstractEAIndividual indy1, AbstractEAIndividual indy2) { double result = 0; + // results are added up because individuals can implement several data types! if ((indy1 instanceof InterfaceDataTypeBinary) && (indy2 instanceof InterfaceDataTypeBinary)) { - BitSet b1, b2; - int l1, l2; - double tmpResult = 0; - b1 = ((InterfaceDataTypeBinary) indy1).getBinaryData(); - b2 = ((InterfaceDataTypeBinary) indy2).getBinaryData(); - l1 = ((InterfaceDataTypeBinary) indy1).size(); - l2 = ((InterfaceDataTypeBinary) indy2).size(); - for (int i = 0; (i < l1) && (i < l2); i++) { - if (b1.get(i)==b2.get(i)) tmpResult += 1; - } - result += tmpResult/((double)Math.min(l1,l2)); + if (bitMetric == null) bitMetric = new GenotypeMetricBitSet(); + result += bitMetric.distance(indy1, indy2); } if ((indy1 instanceof InterfaceDataTypeInteger) && (indy2 instanceof InterfaceDataTypeInteger)) { int[] d1,d2; @@ -222,7 +216,7 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali * @return description */ public String globalInfo() { - return "This is a phenotype based method suited for double data. Metric is computed on a normalized search space."; + return "This is a phenotype based metric which can be applied to binary, integer, double, permutation, and program data types. For the latter two, the Levenshtein distance is computed. All distance values are normed."; } /** This method will return a naming String * @return The name of the algorithm diff --git a/src/eva2/server/go/operators/distancemetric/SigmaSingleMetricGlobalMutation.java b/src/eva2/server/go/operators/distancemetric/SigmaSingleMetricGlobalMutation.java index a3e56884..689bc168 100644 --- a/src/eva2/server/go/operators/distancemetric/SigmaSingleMetricGlobalMutation.java +++ b/src/eva2/server/go/operators/distancemetric/SigmaSingleMetricGlobalMutation.java @@ -64,7 +64,7 @@ public class SigmaSingleMetricGlobalMutation implements InterfaceDistanceMetric, * @return description */ public String globalInfo() { - return "This is a phenotype based method suited for double data. Metric is computed on a normalized search space."; + return "This is an experimental method for individuals using global ES mutation."; } /** This method will return a naming String * @return The name of the algorithm diff --git a/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java b/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java index e42da7b2..fac075dd 100644 --- a/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java +++ b/src/eva2/server/go/operators/mutation/MutateESMutativeStepSizeControl.java @@ -17,14 +17,32 @@ public class MutateESMutativeStepSizeControl implements InterfaceMutation, java. protected double m_MutationStepSize = 0.2; protected double m_Alpha = 1.2; protected double m_LowerLimitStepSize = 0.0000005; + protected double m_UpperLimitStepSize = 0.4; public MutateESMutativeStepSizeControl() { - } + + public MutateESMutativeStepSizeControl(double initialStepSize, double lowerLimit, double upperLimit) { + m_MutationStepSize = initialStepSize; + if (m_LowerLimitStepSize > m_UpperLimitStepSize) { + System.err.println("Invalid step size bounds, switching upper and lower..."); + double tmp = upperLimit; + upperLimit = lowerLimit; + lowerLimit = tmp; + } + m_LowerLimitStepSize = lowerLimit; + m_UpperLimitStepSize = upperLimit; + if (initialStepSize < lowerLimit || initialStepSize > upperLimit) { + m_MutationStepSize = (upperLimit + lowerLimit) /2.; + System.err.println("Invalid initial stepsize, setting it to " + m_MutationStepSize); + } + } + public MutateESMutativeStepSizeControl(MutateESMutativeStepSizeControl mutator) { this.m_MutationStepSize = mutator.m_MutationStepSize; this.m_Alpha = mutator.m_Alpha; this.m_LowerLimitStepSize = mutator.m_LowerLimitStepSize; + this.m_UpperLimitStepSize = mutator.m_UpperLimitStepSize; } /** This method will enable you to clone a given mutation operator @@ -44,6 +62,7 @@ public class MutateESMutativeStepSizeControl implements InterfaceMutation, java. if (this.m_MutationStepSize != mut.m_MutationStepSize) return false; if (this.m_Alpha != mut.m_Alpha) return false; if (this.m_LowerLimitStepSize != mut.m_LowerLimitStepSize) return false; + if (this.m_UpperLimitStepSize != mut.m_UpperLimitStepSize) return false; return true; } else return false; } @@ -70,13 +89,14 @@ public class MutateESMutativeStepSizeControl implements InterfaceMutation, java. else this.m_MutationStepSize = this.m_MutationStepSize / this.m_Alpha; if (this.m_MutationStepSize < this.m_LowerLimitStepSize) this.m_MutationStepSize = this.m_LowerLimitStepSize; + if (this.m_MutationStepSize > this.m_UpperLimitStepSize) this.m_MutationStepSize = this.m_UpperLimitStepSize; for (int i = 0; i < x.length; i++) { x[i] += ((range[i][1] -range[i][0])/2)*RNG.gaussianDouble(this.m_MutationStepSize); if (range[i][0] > x[i]) x[i] = range[i][0]; 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("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor()); } @@ -133,7 +153,6 @@ public class MutateESMutativeStepSizeControl implements InterfaceMutation, java. * @param d The mutation operator. */ public void setLowerLimitStepSize(double d) { - if (d < 1) d = 1; this.m_LowerLimitStepSize = d; } public double getLowerLimitStepSize() { @@ -142,6 +161,19 @@ public class MutateESMutativeStepSizeControl implements InterfaceMutation, java. public String lowerLimitStepSizeTipText() { return "Set the lower limit for the mutation step size."; } + + /** Set the upper limit for the mutation step size with this method. + * @param d The mutation operator. + */ + public void setUpperLimitStepSize(double d) { + this.m_UpperLimitStepSize = d; + } + public double getUpperLimitStepSize() { + return this.m_UpperLimitStepSize; + } + public String upperLimitStepSizeTipText() { + return "Set the upper limit for the mutation step size."; + } /** Set the value for Alpha with this method. * @param d The mutation operator. diff --git a/src/eva2/server/go/operators/postprocess/PostProcess.java b/src/eva2/server/go/operators/postprocess/PostProcess.java index c64211eb..3f1afc5e 100644 --- a/src/eva2/server/go/operators/postprocess/PostProcess.java +++ b/src/eva2/server/go/operators/postprocess/PostProcess.java @@ -12,7 +12,9 @@ import eva2.server.go.operators.cluster.InterfaceClustering; import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric; import eva2.server.go.operators.distancemetric.PhenotypeMetric; import eva2.server.go.operators.mutation.InterfaceMutation; +import eva2.server.go.operators.mutation.MutateESCovarianceMartixAdaption; import eva2.server.go.operators.mutation.MutateESFixedStepSize; +import eva2.server.go.operators.mutation.MutateESMutativeStepSizeControl; import eva2.server.go.operators.terminators.EvaluationTerminator; import eva2.server.go.populations.Population; import eva2.server.go.problems.AbstractMultiModalProblemKnown; @@ -35,6 +37,8 @@ public class PostProcess { private static final boolean TRACE = false; // the default mutation step size for HC post processing private static double defaultMutationStepSize = 0.01; + // lower limit mutation step size for HC post processing + private static double minMutationStepSize = 0.0000000000000001; // used for hill climbing post processing and only alive during that period private static OptimizerRunnable hcRunnable = null; @@ -316,24 +320,38 @@ public class PostProcess { /** * Optimize a population with a default hill-climbing heuristic for a number of fitness evaluations. - * As mutation operator, a fixed step size ES mutation is used. + * As mutation operator, a mutative step size ES mutation is used, the step size of which is not allowed + * to increase above the initial stepSize. Returns the number of evaluations actually performed, which + * may be slightly above the maxSteps given. * - * @param pop - * @param problem - * @param maxSteps - * @param fixedStepSize + * @param pop the set of individuals to work on + * @param problem the optimization problem + * @param maxSteps the number of evaluations to perform during HC + * @param stepSize the initial mutation step size + * @param minStepSize the minimal step size allowed for a mutation + * @return the number of evaluations actually performed */ - public static int processWithHC(Population pop, AbstractOptimizationProblem problem, int maxSteps, double fixedStepSize) { + public static int processWithHC(Population pop, AbstractOptimizationProblem problem, int maxSteps, double stepSize, double minStepSize) { // pop.SetFunctionCalls(0); // or else optimization wont restart on an "old" population // pop.setGenerationTo(0); int stepsBef = pop.getFunctionCalls(); - processWithHC(pop, problem, new EvaluationTerminator(pop.getFunctionCalls()+maxSteps), new MutateESFixedStepSize(fixedStepSize)); + processWithHC(pop, problem, new EvaluationTerminator(pop.getFunctionCalls()+maxSteps), new MutateESMutativeStepSizeControl(stepSize, minStepSize, stepSize)); return pop.getFunctionCalls()-stepsBef; } + /** + * Perform hill climbing with default mutation parameters. + * + * @see processWithHC(Population pop, AbstractOptimizationProblem problem, int maxSteps, double stepSize, double minStepSize) + * @param pop + * @param problem + * @param maxSteps + * @return the number of evaluations actually performed + */ public static int processWithHC(Population pop, AbstractOptimizationProblem problem, int maxSteps) { - return processWithHC(pop, problem, maxSteps, defaultMutationStepSize); + return processWithHC(pop, problem, maxSteps, defaultMutationStepSize, minMutationStepSize); } + /** * Optimize a population with a default hill-climbing heuristic with a given termination criterion and mutation operator. * @@ -346,6 +364,7 @@ public class PostProcess { HillClimbing hc = new HillClimbing(); // HC depends heavily on the selected mutation operator! hc.SetProblem(problem); + mute.init(problem.getIndividualTemplate(), problem); hc.SetMutationOperator(mute); if (pop.size() != pop.getPopulationSize()) { System.err.println(pop.size() + " vs. "+ pop.getPopulationSize()); @@ -480,11 +499,12 @@ public class PostProcess { if (listener != null) { listener.println("number of known optima is " + mmkProb.getRealOptima().size()); listener.println("default epsilon is " + mmkProb.getEpsilon()); + listener.println("optima found with default epsilon: " + getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getEpsilon(), true).size()); listener.println("max peak ratio is " + mmkProb.getMaximumPeakRatio(getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getEpsilon(), true))); - } - for (double epsilon=0.1; epsilon > 0.00000001; epsilon/=10.) { - // out.println("no optima found: " + ((InterfaceMultimodalProblemKnown)mmProb).getNumberOfFoundOptima(pop)); - if (listener != null) listener.println("found " + getFoundOptima(solutions, mmkProb.getRealOptima(), epsilon, true).size() + " for epsilon = " + epsilon + ", maxPeakRatio: " + ((AbstractMultiModalProblemKnown)mmkProb).getMaximumPeakRatio(solutions, epsilon)); + for (double epsilon=0.1; epsilon > 0.00000001; epsilon/=10.) { + // out.println("no optima found: " + ((InterfaceMultimodalProblemKnown)mmProb).getNumberOfFoundOptima(pop)); + listener.println("found " + getFoundOptima(solutions, mmkProb.getRealOptima(), epsilon, true).size() + " for epsilon = " + epsilon + ", maxPeakRatio: " + ((AbstractMultiModalProblemKnown)mmkProb).getMaximumPeakRatio(solutions, epsilon)); + } } } diff --git a/src/eva2/server/go/operators/terminators/CombinedTerminator.java b/src/eva2/server/go/operators/terminators/CombinedTerminator.java index 1c70a80d..3ce83f9c 100644 --- a/src/eva2/server/go/operators/terminators/CombinedTerminator.java +++ b/src/eva2/server/go/operators/terminators/CombinedTerminator.java @@ -4,6 +4,8 @@ import java.io.Serializable; import eva2.server.go.InterfaceTerminator; import eva2.server.go.PopulationInterface; +import eva2.server.go.populations.InterfaceSolutionSet; +import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.tools.SelectedTag; @@ -15,6 +17,7 @@ public class CombinedTerminator implements InterfaceTerminator, Serializable { private InterfaceTerminator t1 = new FitnessConvergenceTerminator(); private InterfaceTerminator t2 = new EvaluationTerminator(); private SelectedTag andOrTag = new SelectedTag("OR", "AND"); + private String msg = null; public static final boolean AND = true; public static final boolean OR = false; @@ -38,46 +41,52 @@ public class CombinedTerminator implements InterfaceTerminator, Serializable { return "Boolean combination of two terminators."; } - public void init() { - if (t1 != null) t1.init(); - if (t2 != null) t2.init(); + public void init(InterfaceOptimizationProblem prob) { + if (t1 != null) t1.init(prob); + if (t2 != null) t2.init(prob); + msg = "Not terminated."; } + public boolean isTerminated(InterfaceSolutionSet solSet) { + return isTerminated(solSet.getCurrentPopulation()); + } + public boolean isTerminated(PopulationInterface pop) { boolean ret; if ((t1 == null) && (t2 == null)) { System.err.println("Error: No terminator set in CombinedTerminator"); return true; } - if (t1 == null) return t2.isTerminated(pop); - if (t2 == null) return t1.isTerminated(pop); + if (t1 == null) { + ret = t2.isTerminated(pop); + msg = t2.lastTerminationMessage(); + return ret; + } + if (t2 == null) { + ret = t1.isTerminated(pop); + msg = t1.lastTerminationMessage(); + return ret; + } if (andOrTag.isSelectedString("AND")) { // make sure that both terminators are triggered by every call, because some judge // time-dependently and store information on the population. ret = t1.isTerminated(pop); ret = ret && t2.isTerminated(pop); + if (ret) msg = "Terminated because both: " + t1.lastTerminationMessage() + " And " + t2.lastTerminationMessage(); } else { // OR // make sure that both terminators are triggered by every call, because some judge // time-dependently and store information on the population. ret = t1.isTerminated(pop); + if (ret) msg = t1.lastTerminationMessage(); ret = ret || t2.isTerminated(pop); + if (ret) msg = t2.lastTerminationMessage(); } return ret; } - public String terminatedBecause(PopulationInterface pop) { - if (isTerminated(pop)) { - if (andOrTag.isSelectedString("AND")) { - return "Terminated because both: " + t1.terminatedBecause(pop) + " And " + t2.terminatedBecause(pop); - } else { - if ((t1 != null) && (t1.isTerminated(pop))) { - return t1.terminatedBecause(pop); - } else { - return t2.terminatedBecause(pop); - } - } - } else return "not terminated"; + public String lastTerminationMessage() { + return msg; } /** diff --git a/src/eva2/server/go/operators/terminators/DiversityTerminator.java b/src/eva2/server/go/operators/terminators/DiversityTerminator.java new file mode 100644 index 00000000..ab75e23e --- /dev/null +++ b/src/eva2/server/go/operators/terminators/DiversityTerminator.java @@ -0,0 +1,143 @@ +package eva2.server.go.operators.terminators; + +import java.io.Serializable; + +import eva2.server.go.InterfaceTerminator; +import eva2.server.go.PopulationInterface; +import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric; +import eva2.server.go.operators.distancemetric.PhenotypeMetric; +import eva2.server.go.populations.InterfaceSolutionSet; +import eva2.server.go.populations.Population; +import eva2.server.go.problems.InterfaceOptimizationProblem; +import eva2.tools.SelectedTag; + +/** + * The diversity terminator uses the distance of individuals + * in the population as termination criterion. If the average distance + * sinks below the given limit, the optimization stops. + * May be computationally expensive. + * + * @see Population.getPopulationMeasures() + * @see PhenotypeMetric + * @author mkron + * + */ +public class DiversityTerminator implements InterfaceTerminator, Serializable { + private double distanceLimit = 0.001; + private InterfaceDistanceMetric metric = new PhenotypeMetric(); + private String msg = ""; + // leave the string order for this SelectedTag! (analogy to Population.getPopulationMeasures) + private SelectedTag criterion = new SelectedTag("Average distance", "Minimum distance", "Maximum distance"); + + public DiversityTerminator() {} + + /** + * The default uses Phenotype metric and average distance as criterion. + * + * @param limit + */ + public DiversityTerminator(double limit) { + distanceLimit = limit; + metric = new PhenotypeMetric(); + criterion.setSelectedTag(0); + } + + /** + * Create a special DiversityTerminator defining distance limit, metric and distance + * criterion to use (average, minimum or maximum distance). + * + * @param limit the distance limit of individuals below which termination is triggered + * @param metric the metric to be used to calculate individual distances + * @param criterionID 0 for average distance, 1 for minimum distance and 2 for maximum distance + */ + public DiversityTerminator(double limit, InterfaceDistanceMetric metric, int criterionID) { + distanceLimit = limit; + this.metric = metric; + criterion.setSelectedTag(criterionID); + } + + public void init(InterfaceOptimizationProblem prob) { + msg = "Not terminated."; + } + + public String globalInfo() { + return "The diversity terminator uses the distance of individuals in the population as a termination criterion."; + } + + /** + * Returns true if the average phenotypic distance within the given + * population is below the limit set in the terminator instance. + * + * @return true if the population is seen as converged due to low average phenotypic distance, else false + */ + public boolean isTerminated(PopulationInterface pop) { + double[] measures = ((Population)pop).getPopulationMeasures(metric); + int measureIndex = criterion.getSelectedTagID(); + if (measures[measureIndex] < distanceLimit) { + msg = "Average individual distance below " + distanceLimit; + return true; + } else return false; + } + + public boolean isTerminated(InterfaceSolutionSet sols) { + return isTerminated(sols.getCurrentPopulation()); + } + + public String lastTerminationMessage() { + return msg; + } + + /** + * @return the avgDistanceLimit + */ + public double getDistanceLimit() { + return distanceLimit; + } + + /** + * @param avgDistanceLimit the avgDistanceLimit to set + */ + public void setDistanceLimit(double avgDistanceLimit) { + this.distanceLimit = avgDistanceLimit; + } + + public String distanceLimitTipText() { + return "Set the distance limit of individuals below which termination is triggered."; + } + + /** + * @return the metric + */ + public InterfaceDistanceMetric getMetric() { + return metric; + } + + /** + * @param metric the metric to set + */ + public void setMetric(InterfaceDistanceMetric metric) { + this.metric = metric; + } + + public String metricTipText() { + return "Set the metric to be used to calculate individual distances."; + } + + /** + * @return the criterion + */ + public SelectedTag getCriterion() { + return criterion; + } + + /** + * @param criterion the criterion to set + */ + public void setCriterion(SelectedTag criterion) { + this.criterion = criterion; + } + + public String criterionTipText() { + return "Define the distance criterion to check for in a population."; + } +} diff --git a/src/eva2/server/go/operators/terminators/EvaluationTerminator.java b/src/eva2/server/go/operators/terminators/EvaluationTerminator.java index 721aab8e..8647ed9b 100644 --- a/src/eva2/server/go/operators/terminators/EvaluationTerminator.java +++ b/src/eva2/server/go/operators/terminators/EvaluationTerminator.java @@ -16,80 +16,80 @@ import java.io.Serializable; import eva2.server.go.InterfaceTerminator; import eva2.server.go.PopulationInterface; +import eva2.server.go.populations.InterfaceSolutionSet; +import eva2.server.go.problems.InterfaceOptimizationProblem; /*==========================================================================* -* CLASS DECLARATION -*==========================================================================*/ + * CLASS DECLARATION + *==========================================================================*/ /** * */ public class EvaluationTerminator implements InterfaceTerminator, - Serializable { - /** - * Number of fitness calls on the problem which is optimized. - */ - protected int m_FitnessCalls = 1000; - /** - * - */ - public EvaluationTerminator() { - } - public void init(){} - /** - * - */ - public String globalInfo() { - return "Terminates after the given number of fitness calls."; - } - - /** - * Construct Terminator with a maximum number of fitness calls. - * @param maximum number of fitness calls - */ - public EvaluationTerminator(int x) { - m_FitnessCalls = x; - } - /** - * - */ - public boolean isTerminated(PopulationInterface pop) { - //System.out.println("m_FitnessCalls="+m_FitnessCalls); - if (m_FitnessCalls>pop.getFunctionCalls()) - return false; - return true; - } - - public String terminatedBecause(PopulationInterface pop) { - if (isTerminated(pop)) return m_FitnessCalls + " fitness calls were reached."; - else return "Not yet terminated."; - } - /** - * - */ - public String toString() { - String ret = "EvaluationTerminator,calls="+m_FitnessCalls; - return ret; - } - /** - * - */ - public void setFitnessCalls(int x) { - //System.out.println("setFitnessCalls"+x); - m_FitnessCalls = x; - } - /** - * - */ - public int getFitnessCalls() { - //System.out.println("getFitnessCalls"+m_FitnessCalls); - return m_FitnessCalls; - } - /** - * Returns the tip text for this property - * @return tip text for this property - */ - public String fitnessCallsTipText() { - return "number of calls to fitness function."; - } +Serializable { + private String msg = "Not terminated."; + /** + * Number of fitness calls on the problem which is optimized. + */ + protected int m_FitnessCalls = 1000; + + public EvaluationTerminator() { + } + + public void init(InterfaceOptimizationProblem prob){ + msg = "Not terminated."; + } + + public String globalInfo() { + return "Terminates after the given number of fitness calls."; + } + + /** + * Construct Terminator with a maximum number of fitness calls. + * @param maximum number of fitness calls + */ + public EvaluationTerminator(int x) { + m_FitnessCalls = x; + } + + public boolean isTerminated(InterfaceSolutionSet solSet) { + return isTerminated(solSet.getCurrentPopulation()); + } + + public boolean isTerminated(PopulationInterface pop) { + //System.out.println("m_FitnessCalls="+m_FitnessCalls); + if (m_FitnessCalls>pop.getFunctionCalls()) return false; + else { + msg = m_FitnessCalls + " fitness calls were reached."; + return true; + } + } + + public String lastTerminationMessage() { + return msg; + } + + public String toString() { + String ret = "EvaluationTerminator,calls="+m_FitnessCalls; + return ret; + } + + public void setFitnessCalls(int x) { + //System.out.println("setFitnessCalls"+x); + m_FitnessCalls = x; + } + + public int getFitnessCalls() { + //System.out.println("getFitnessCalls"+m_FitnessCalls); + return m_FitnessCalls; + } + + /** + * Returns the tip text for this property + * @return tip text for this property + */ + public String fitnessCallsTipText() { + return "number of calls to fitness function."; + } } \ No newline at end of file diff --git a/src/eva2/server/go/operators/terminators/FitnessConvergenceTerminator.java b/src/eva2/server/go/operators/terminators/FitnessConvergenceTerminator.java index fb91ee12..23be78b8 100644 --- a/src/eva2/server/go/operators/terminators/FitnessConvergenceTerminator.java +++ b/src/eva2/server/go/operators/terminators/FitnessConvergenceTerminator.java @@ -21,6 +21,8 @@ import eva2.server.go.InterfaceTerminator; import eva2.server.go.PopulationInterface; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.operators.distancemetric.PhenotypeMetric; +import eva2.server.go.populations.InterfaceSolutionSet; +import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.tools.SelectedTag; @@ -43,6 +45,8 @@ Serializable { protected double oldNorm; private SelectedTag stagnationMeasure = new SelectedTag("Fitness calls", "Generations"); private SelectedTag convergenceCondition = new SelectedTag("Relative", "Absolute"); + private String msg=""; + protected String tagString = "Fitness converged"; PhenotypeMetric pMetric = null; public FitnessConvergenceTerminator() { @@ -66,15 +70,22 @@ Serializable { return "Stop if a fitness convergence criterion has been met."; } - public void init() { + public void init(InterfaceOptimizationProblem prob) { if (pMetric == null) pMetric = new PhenotypeMetric(); firstTime = true; + msg = "Not terminated."; + tagString = "Fitness converged"; } + public boolean isTerminated(InterfaceSolutionSet solSet) { + return isTerminated(solSet.getCurrentPopulation()); + } + public boolean isTerminated(PopulationInterface Pop) { if (!firstTime && isStillConverged(Pop.getBestIndividual())) { if (stagnationTimeHasPassed(Pop)) { // population hasnt improved much for max time, criterion is met + msg = getTerminationMessage(tagString); return true; } else { // population hasnt improved much for ifit[i]) return false; } + msg = "Fitness value below " + BeanInspector.toString(m_FitnessValue); return true; } - public String terminatedBecause(PopulationInterface pop) { - if (isTerminated(pop)) { - return "Fitness value below " + BeanInspector.toString(m_FitnessValue); - } else return "Not yet terminated."; + public String lastTerminationMessage() { + return msg; } /** diff --git a/src/eva2/server/go/operators/terminators/GenerationTerminator.java b/src/eva2/server/go/operators/terminators/GenerationTerminator.java index 7e85ee63..f1faa5ad 100644 --- a/src/eva2/server/go/operators/terminators/GenerationTerminator.java +++ b/src/eva2/server/go/operators/terminators/GenerationTerminator.java @@ -17,75 +17,72 @@ import java.io.Serializable; import eva2.gui.BeanInspector; import eva2.server.go.InterfaceTerminator; import eva2.server.go.PopulationInterface; +import eva2.server.go.populations.InterfaceSolutionSet; +import eva2.server.go.problems.InterfaceOptimizationProblem; /*==========================================================================* -* CLASS DECLARATION -*==========================================================================*/ + * CLASS DECLARATION + *==========================================================================*/ /** * */ public class GenerationTerminator implements InterfaceTerminator, - Serializable { - /** - * Number of fitness calls on the problem which is optimized - */ - protected int m_Generations = 100; - public void init(){} - /** - * - */ - public String globalInfo() { - return "Terminate after the given number of generations"; - } - /** - * - */ - public GenerationTerminator() { - } - /** - * - */ - public GenerationTerminator(int gens) { - m_Generations = gens; - } - /** - * - */ - public boolean isTerminated(PopulationInterface Pop) { - if (m_Generations= reqOptima) { + msg = "There were " + reqOptima + " optima found."; + return true; + } else return false; + } + + public String lastTerminationMessage() { + return msg; + } + + /** + * @return the reqOptima + */ + public int getReqOptima() { + return reqOptima; + } + + /** + * @param reqOptima the reqOptima to set + */ + public void setReqOptima(int reqOptima) { + this.reqOptima = reqOptima; + } + + public String reqOptimaTipText() { + return "The number of optima that need to be found to terminate the optimization."; + } + + public String toString() { + return "KnownOptimaFoundTerminator requiring " + reqOptima + " optima."; + } + + public String globalInfo() { + return "Terminate if a given number of optima has been found. Works for problems implementing InterfaceMultimodalProblemKnown, e.g. FM0."; + } +} diff --git a/src/eva2/server/go/operators/terminators/PhenotypeConvergenceTerminator.java b/src/eva2/server/go/operators/terminators/PhenotypeConvergenceTerminator.java index 553ca808..0cd84a73 100644 --- a/src/eva2/server/go/operators/terminators/PhenotypeConvergenceTerminator.java +++ b/src/eva2/server/go/operators/terminators/PhenotypeConvergenceTerminator.java @@ -6,6 +6,7 @@ import eva2.server.go.InterfaceTerminator; import eva2.server.go.PopulationInterface; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.operators.distancemetric.PhenotypeMetric; +import eva2.server.go.problems.InterfaceOptimizationProblem; public class PhenotypeConvergenceTerminator extends FitnessConvergenceTerminator implements InterfaceTerminator { AbstractEAIndividual oldIndy = null; @@ -13,11 +14,18 @@ public class PhenotypeConvergenceTerminator extends FitnessConvergenceTerminator public PhenotypeConvergenceTerminator() { super(); + tagString = "Phenotype converged"; } public PhenotypeConvergenceTerminator(double thresh, int stagnTime, boolean bFitCallBased, boolean bAbsolute) { super(thresh, stagnTime, bFitCallBased, bAbsolute); } + + public void init(InterfaceOptimizationProblem prob) { + super.init(prob); + tagString = "Phenotype converged"; + } + /** * Return true if |oldPhen - curPhen| < |oldPhen| * thresh (relative case) * and if |oldFit - curFit| < thresh (absolute case). @@ -36,14 +44,7 @@ public class PhenotypeConvergenceTerminator extends FitnessConvergenceTerminator if (TRACE) System.out.println("isStillConverged returns " + ret + ", dist " + dist + ", old indy " + BeanInspector.toString(oldIndy) + ", cur indy" + BeanInspector.toString(indy)); return ret; } - - public String terminatedBecause(PopulationInterface pop) { - if (isTerminated(pop)) { - return getTerminationMessage("Phenotype converged"); - } else return "Not yet terminated."; - } - protected void saveState(PopulationInterface Pop) { super.saveState(Pop); oldIndy = (AbstractEAIndividual)((AbstractEAIndividual)Pop.getBestIndividual()).clone(); diff --git a/src/eva2/server/go/populations/InterfaceSolutionSet.java b/src/eva2/server/go/populations/InterfaceSolutionSet.java new file mode 100644 index 00000000..52991586 --- /dev/null +++ b/src/eva2/server/go/populations/InterfaceSolutionSet.java @@ -0,0 +1,16 @@ +package eva2.server.go.populations; + +/** + * This is just a wrapper type to distinct between a Population (current solution set + * of an optimizer) and a final solution set, in which archived and deactivated + * individuals may be contained as well. Both may be equal if the optimizer doesnt + * make this distinction. + * + * @author mkron + * + */ +public interface InterfaceSolutionSet { + public Population getSolutions(); + public Population getCurrentPopulation(); + public SolutionSet clone(); +} diff --git a/src/eva2/server/go/populations/Population.java b/src/eva2/server/go/populations/Population.java index e123871c..b0456bdd 100644 --- a/src/eva2/server/go/populations/Population.java +++ b/src/eva2/server/go/populations/Population.java @@ -13,6 +13,7 @@ import eva2.server.go.PopulationInterface; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.AbstractEAIndividualComparator; import eva2.server.go.individuals.GAIndividualBinaryData; +import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric; import eva2.server.go.operators.distancemetric.PhenotypeMetric; import eva2.tools.EVAERROR; import eva2.tools.Mathematics; @@ -90,6 +91,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea } } + public void addData(String key, Object value) { + if (additionalPopData == null) additionalPopData = new HashMap(); + additionalPopData.put(key, value); + } + + public Object getData(String key) { + if (additionalPopData == null) return null; + else return additionalPopData.get(key); + } + public Object clone() { return (Object) new Population(this); } @@ -724,8 +735,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea * @return the average, minimal and maximal mean distance of individuals in an array of three */ public double[] getPopulationMeasures() { - PhenotypeMetric metric = new PhenotypeMetric(); - + return getPopulationMeasures(new PhenotypeMetric()); + } + + /** + * Returns the average, minimal and maximal individual distance as diversity measure for the population. + * This is of course rather expensive computationally. + * + * @return the average, minimal and maximal mean distance of individuals in an array of three + */ + public double[] getPopulationMeasures(InterfaceDistanceMetric metric) { double d; double[] res = new double[3]; diff --git a/src/eva2/server/go/populations/SolutionSet.java b/src/eva2/server/go/populations/SolutionSet.java new file mode 100644 index 00000000..3e2dd6de --- /dev/null +++ b/src/eva2/server/go/populations/SolutionSet.java @@ -0,0 +1,34 @@ +package eva2.server.go.populations; + +public class SolutionSet implements InterfaceSolutionSet { + Population pop = null; + Population sols = null; + + public SolutionSet(Population currentPop, Population allSols) { + pop = currentPop; + sols = allSols; + } + + /** + * Create a solution set from a single population. This can be used by optimizers which + * make no distinction between current solution set and archived solution set. + * + * @param p + */ + public SolutionSet(Population p) { + pop = p; + sols = p; + } + + public SolutionSet clone() { + return new SolutionSet((Population)pop.clone(), (Population)sols.clone()); + } + + public Population getSolutions() { + return sols; + } + + public Population getCurrentPopulation() { + return pop; + } +} diff --git a/src/eva2/server/go/problems/MatlabProblem.java b/src/eva2/server/go/problems/MatlabProblem.java index d6079d41..8c860e6f 100644 --- a/src/eva2/server/go/problems/MatlabProblem.java +++ b/src/eva2/server/go/problems/MatlabProblem.java @@ -444,7 +444,7 @@ class WaitForEvARunnable implements Runnable { } try { mp.log("runnable.getSolution: " + BeanInspector.toString(runnable.getDoubleSolution())); - mp.log("\ngetAllSols best: " + AbstractEAIndividual.getDefaultDataString(runnable.getGOParams().getOptimizer().getAllSolutions().getBestEAIndividual())); + mp.log("\ngetAllSols best: " + AbstractEAIndividual.getDefaultDataString(runnable.getGOParams().getOptimizer().getAllSolutions().getSolutions().getBestEAIndividual())); mp.log("\n"); // write results back to matlab mp.exportResultToMatlab(runnable.getDoubleSolution()); diff --git a/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java b/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java index 8463387e..236987a7 100644 --- a/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java +++ b/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java @@ -3,17 +3,18 @@ package eva2.server.go.strategies; import java.util.BitSet; +import wsi.ra.math.RNG; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.InterfaceGAIndividual; import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectBestSingle; import eva2.server.go.operators.selection.SelectRandom; -import eva2.server.go.populations.PBILPopulation; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -import wsi.ra.math.RNG; /** This is an implementation of the CHC Adaptive Search Algorithm by Eselman. It is * limited to binary data and is based on massively distruptive crossover. I'm not @@ -295,8 +296,8 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } // /** This method will set the normation method that is to be used. diff --git a/src/eva2/server/go/strategies/ClusterBasedNichingEA.java b/src/eva2/server/go/strategies/ClusterBasedNichingEA.java index 79aba028..0cde2b0b 100644 --- a/src/eva2/server/go/strategies/ClusterBasedNichingEA.java +++ b/src/eva2/server/go/strategies/ClusterBasedNichingEA.java @@ -19,8 +19,9 @@ import eva2.server.go.operators.cluster.ClusteringDensityBased; import eva2.server.go.operators.cluster.InterfaceClustering; import eva2.server.go.operators.mutation.InterfaceMutation; import eva2.server.go.operators.mutation.MutateESGlobal; -//import eva2.server.go.populations.Distraction; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.Interface2DBorderProblem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -730,12 +731,12 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis return "Edit the properties of the population used."; } - public Population getAllSolutions() { + public InterfaceSolutionSet getAllSolutions() { // return inactive species - Population pop = (Population)m_Archive.clone(); - pop.addPopulation(getPopulation()); - pop.setPopulationSize(pop.size()); - return pop; + Population sols = (Population)m_Archive.clone(); + sols.addPopulation(getPopulation()); + sols.setPopulationSize(sols.size()); + return new SolutionSet(getPopulation(), sols); } /** This method allows you to set/get the switch that toggles the use diff --git a/src/eva2/server/go/strategies/ClusteringHillClimbing.java b/src/eva2/server/go/strategies/ClusteringHillClimbing.java index c5fd2fb7..c34e1a02 100644 --- a/src/eva2/server/go/strategies/ClusteringHillClimbing.java +++ b/src/eva2/server/go/strategies/ClusteringHillClimbing.java @@ -6,7 +6,9 @@ import eva2.gui.GenericObjectEditor; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.operators.mutation.MutateESFixedStepSize; import eva2.server.go.operators.postprocess.PostProcess; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -207,13 +209,16 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi return "Change the number of starting individuals stored (Cluster-HC)."; } - public Population getAllSolutions() { + public InterfaceSolutionSet getAllSolutions() { Population tmp = new Population(); tmp.addPopulation(archive); tmp.addPopulation(m_Population); + tmp.SetFunctionCalls(m_Population.getFunctionCalls()); + tmp.setGenerationTo(m_Population.getGeneration()); // tmp = PostProcessInterim.clusterBest(tmp, sigma, 0, PostProcessInterim.KEEP_LONERS, PostProcessInterim.BEST_ONLY); - return tmp; + return new SolutionSet(m_Population, tmp); } + /** This method will return a string describing all properties of the optimizer * and the applied methods. * @return A descriptive string diff --git a/src/eva2/server/go/strategies/DifferentialEvolution.java b/src/eva2/server/go/strategies/DifferentialEvolution.java index e5d52401..2cd48e54 100644 --- a/src/eva2/server/go/strategies/DifferentialEvolution.java +++ b/src/eva2/server/go/strategies/DifferentialEvolution.java @@ -8,7 +8,9 @@ import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.InterfaceESIndividual; import eva2.server.go.operators.selection.replacement.ReplacementCrowding; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.AbstractMultiObjectiveOptimizationProblem; import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.F1Problem; @@ -516,8 +518,9 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + Population pop = getPopulation(); + return new SolutionSet(pop, pop); } /** F is a real and constant factor which controls the amplification of the differential variation diff --git a/src/eva2/server/go/strategies/EvolutionStrategies.java b/src/eva2/server/go/strategies/EvolutionStrategies.java index 931b13fb..41fc7666 100644 --- a/src/eva2/server/go/strategies/EvolutionStrategies.java +++ b/src/eva2/server/go/strategies/EvolutionStrategies.java @@ -6,7 +6,9 @@ import eva2.server.go.operators.mutation.MutateESSuccessRule; import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectBestIndividuals; import eva2.server.go.operators.selection.SelectRandom; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -373,8 +375,8 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } // /** This method will set the normation method that is to be used. // * @param normation diff --git a/src/eva2/server/go/strategies/EvolutionaryProgramming.java b/src/eva2/server/go/strategies/EvolutionaryProgramming.java index 81ef7f4b..bebfae3f 100644 --- a/src/eva2/server/go/strategies/EvolutionaryProgramming.java +++ b/src/eva2/server/go/strategies/EvolutionaryProgramming.java @@ -5,7 +5,9 @@ import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.GAIndividualBinaryData; import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectEPTournaments; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -199,8 +201,8 @@ public class EvolutionaryProgramming implements InterfaceOptimizer, java.io.Seri return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** Choose a method for selecting the reduced population. * @param selection diff --git a/src/eva2/server/go/strategies/FloodAlgorithm.java b/src/eva2/server/go/strategies/FloodAlgorithm.java index 07a1d413..eccbcce7 100644 --- a/src/eva2/server/go/strategies/FloodAlgorithm.java +++ b/src/eva2/server/go/strategies/FloodAlgorithm.java @@ -3,7 +3,9 @@ package eva2.server.go.strategies; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.GAIndividualBinaryData; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -234,8 +236,8 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** This methods allow you to set/get the temperatur of the flood * algorithm procedure diff --git a/src/eva2/server/go/strategies/GeneticAlgorithm.java b/src/eva2/server/go/strategies/GeneticAlgorithm.java index 1d384b04..de7aa4e2 100644 --- a/src/eva2/server/go/strategies/GeneticAlgorithm.java +++ b/src/eva2/server/go/strategies/GeneticAlgorithm.java @@ -5,7 +5,9 @@ import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.GAIndividualBinaryData; import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectTournament; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -238,8 +240,8 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } // /** This method will set the normation method that is to be used. // * @param normation diff --git a/src/eva2/server/go/strategies/GradientDescentAlgorithm.java b/src/eva2/server/go/strategies/GradientDescentAlgorithm.java index f3fea8f3..409ac9bc 100644 --- a/src/eva2/server/go/strategies/GradientDescentAlgorithm.java +++ b/src/eva2/server/go/strategies/GradientDescentAlgorithm.java @@ -5,7 +5,9 @@ import java.util.*; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.InterfaceDataTypeDouble; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.InterfaceFirstOrderDerivableProblem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -256,8 +258,8 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser return this.m_Population; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } public void setPopulation(Population pop) { diff --git a/src/eva2/server/go/strategies/HillClimbing.java b/src/eva2/server/go/strategies/HillClimbing.java index ce398bf4..15928cb2 100644 --- a/src/eva2/server/go/strategies/HillClimbing.java +++ b/src/eva2/server/go/strategies/HillClimbing.java @@ -4,7 +4,9 @@ import eva2.gui.BeanInspector; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.operators.mutation.InterfaceMutation; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -235,8 +237,8 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { this.m_Population = pop; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } public String populationTipText() { return "Change the number of best individuals stored (MS-HC)."; diff --git a/src/eva2/server/go/strategies/InterfaceOptimizer.java b/src/eva2/server/go/strategies/InterfaceOptimizer.java index 180fb598..8c029635 100644 --- a/src/eva2/server/go/strategies/InterfaceOptimizer.java +++ b/src/eva2/server/go/strategies/InterfaceOptimizer.java @@ -1,9 +1,7 @@ package eva2.server.go.strategies; -import java.util.List; - import eva2.server.go.InterfacePopulationChangedEventListener; -import eva2.server.go.individuals.AbstractEAIndividual; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -62,11 +60,15 @@ public interface InterfaceOptimizer { public void setPopulation(Population pop); /** - * Return all found solutions (local optima) if they are not contained in the last population. + * Return all found solutions (local optima) if they are not contained in the current population. Be + * sure to set the Population properties, especially function calls and generation, with respect + * to the ongoing optimization. + * May return the same as getPopulation if the optimizer makes no distinction, i.e. does not collect + * solutions outside the current population. * - * @return A population of found solutions or null if they are contained in the population. + * @return A population of found solutions. */ - public Population getAllSolutions(); + public InterfaceSolutionSet getAllSolutions(); /** * This method allows you to set an identifier for the algorithm diff --git a/src/eva2/server/go/strategies/IslandModelEA.java b/src/eva2/server/go/strategies/IslandModelEA.java index d5cc1d71..4c5f074f 100644 --- a/src/eva2/server/go/strategies/IslandModelEA.java +++ b/src/eva2/server/go/strategies/IslandModelEA.java @@ -9,7 +9,9 @@ import eva2.server.go.operators.migration.MOBestMigration; import eva2.server.go.operators.migration.MOClusteringSeparation; import eva2.server.go.operators.migration.MOConeSeparation; import eva2.server.go.operators.migration.SOBestMigration; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.F8Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -524,10 +526,9 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I return "(Defunct)"; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } - /** This method allows you to set the number of processors in local mode * @param n Number of processors. */ diff --git a/src/eva2/server/go/strategies/MemeticAlgorithm.java b/src/eva2/server/go/strategies/MemeticAlgorithm.java index 99ab4f35..579fd2ce 100644 --- a/src/eva2/server/go/strategies/MemeticAlgorithm.java +++ b/src/eva2/server/go/strategies/MemeticAlgorithm.java @@ -6,7 +6,9 @@ import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectBestIndividuals; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.InterfaceLocalSearchable; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -364,8 +366,8 @@ public class MemeticAlgorithm implements InterfaceOptimizer, this.subsetsize = subsetsize; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } public int getSubsetsize() { return subsetsize; diff --git a/src/eva2/server/go/strategies/MonteCarloSearch.java b/src/eva2/server/go/strategies/MonteCarloSearch.java index cd1a3d57..504ae1b2 100644 --- a/src/eva2/server/go/strategies/MonteCarloSearch.java +++ b/src/eva2/server/go/strategies/MonteCarloSearch.java @@ -3,7 +3,9 @@ package eva2.server.go.strategies; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.GAIndividualBinaryData; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -200,7 +202,7 @@ public class MonteCarloSearch implements InterfaceOptimizer, java.io.Serializabl return "Change the number of best individuals stored."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } } \ No newline at end of file diff --git a/src/eva2/server/go/strategies/MultiObjectiveEA.java b/src/eva2/server/go/strategies/MultiObjectiveEA.java index 42422431..7a1cad18 100644 --- a/src/eva2/server/go/strategies/MultiObjectiveEA.java +++ b/src/eva2/server/go/strategies/MultiObjectiveEA.java @@ -7,7 +7,9 @@ import eva2.server.go.operators.archiving.InformationRetrievalInserting; import eva2.server.go.operators.archiving.InterfaceArchiving; import eva2.server.go.operators.archiving.InterfaceInformationRetrieval; import eva2.server.go.operators.selection.SelectMONonDominated; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -227,8 +229,8 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl return "Edit the properties of the Population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** This method allows you to set/get the optimizing technique to use. diff --git a/src/eva2/server/go/strategies/MultiObjectiveMemeticAlgorithmII.java b/src/eva2/server/go/strategies/MultiObjectiveMemeticAlgorithmII.java index ac581f5b..5751cccb 100644 --- a/src/eva2/server/go/strategies/MultiObjectiveMemeticAlgorithmII.java +++ b/src/eva2/server/go/strategies/MultiObjectiveMemeticAlgorithmII.java @@ -8,7 +8,9 @@ import eva2.server.go.operators.archiving.InterfaceArchiving; import eva2.server.go.operators.archiving.InterfaceInformationRetrieval; import eva2.server.go.operators.selection.SelectMOMAIIDominanceCounter; import eva2.server.go.operators.selection.SelectMONonDominated; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -163,8 +165,8 @@ public class MultiObjectiveMemeticAlgorithmII implements InterfaceOptimizer, jav return "Edit the properties of the Population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** This method allows you to set/get the optimizing technique to use. * @return The current optimizing method diff --git a/src/eva2/server/go/strategies/ParticleFilterOptimization.java b/src/eva2/server/go/strategies/ParticleFilterOptimization.java index 8ff03b57..c5c68433 100644 --- a/src/eva2/server/go/strategies/ParticleFilterOptimization.java +++ b/src/eva2/server/go/strategies/ParticleFilterOptimization.java @@ -9,7 +9,9 @@ import eva2.server.go.individuals.InterfaceESIndividual; import eva2.server.go.operators.mutation.MutateESFixedStepSize; import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectParticleWheel; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -254,8 +256,8 @@ public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.S return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** This method will set the selection method that is to be used * @param selection diff --git a/src/eva2/server/go/strategies/ParticleSwarmOptimization.java b/src/eva2/server/go/strategies/ParticleSwarmOptimization.java index 43790d69..42fa1769 100644 --- a/src/eva2/server/go/strategies/ParticleSwarmOptimization.java +++ b/src/eva2/server/go/strategies/ParticleSwarmOptimization.java @@ -12,7 +12,9 @@ import eva2.server.go.individuals.AbstractEAIndividualComparator; import eva2.server.go.individuals.InterfaceDataTypeDouble; import eva2.server.go.individuals.InterfaceESIndividual; import eva2.server.go.operators.distancemetric.PhenotypeMetric; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.Interface2DBorderProblem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -1538,8 +1540,8 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** This method will set the initial velocity * @param f diff --git a/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java b/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java index 4a780ee3..7597e7d7 100644 --- a/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java +++ b/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java @@ -5,8 +5,10 @@ import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.InterfaceGAIndividual; import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectBestIndividuals; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.PBILPopulation; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -206,8 +208,8 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j return "Edit the properties of the PBIL population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } // /** This method will set the normation method that is to be used. // * @param normation diff --git a/src/eva2/server/go/strategies/SimulatedAnnealing.java b/src/eva2/server/go/strategies/SimulatedAnnealing.java index 9a04261d..3dbcb422 100644 --- a/src/eva2/server/go/strategies/SimulatedAnnealing.java +++ b/src/eva2/server/go/strategies/SimulatedAnnealing.java @@ -3,7 +3,9 @@ package eva2.server.go.strategies; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.GAIndividualBinaryData; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; import wsi.ra.math.RNG; @@ -238,8 +240,8 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa return "Change the number of best individuals stored (MS-SA))."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** Set the initial temperature * @return The initial temperature. diff --git a/src/eva2/server/go/strategies/SteadyStateGA.java b/src/eva2/server/go/strategies/SteadyStateGA.java index 3a1964cc..c98c434f 100644 --- a/src/eva2/server/go/strategies/SteadyStateGA.java +++ b/src/eva2/server/go/strategies/SteadyStateGA.java @@ -7,7 +7,9 @@ import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.selection.SelectTournament; import eva2.server.go.operators.selection.replacement.InterfaceReplacement; import eva2.server.go.operators.selection.replacement.ReplaceWorst; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -191,8 +193,8 @@ public class SteadyStateGA implements InterfaceOptimizer, java.io.Serializable { return "Edit the properties of the population used."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** This method will set the parent selection method that is to be used * @param selection diff --git a/src/eva2/server/go/strategies/ThresholdAlgorithm.java b/src/eva2/server/go/strategies/ThresholdAlgorithm.java index 97f18b33..b0dc5fd8 100644 --- a/src/eva2/server/go/strategies/ThresholdAlgorithm.java +++ b/src/eva2/server/go/strategies/ThresholdAlgorithm.java @@ -3,7 +3,9 @@ package eva2.server.go.strategies; import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.GAIndividualBinaryData; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; import wsi.ra.math.RNG; @@ -230,8 +232,8 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa return "Change the number of best individuals stored (MS-TA)."; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** Set the initial threshold * @return The initial temperature. diff --git a/src/eva2/server/go/strategies/Tribes.java b/src/eva2/server/go/strategies/Tribes.java index 8d43081b..ea4dc433 100644 --- a/src/eva2/server/go/strategies/Tribes.java +++ b/src/eva2/server/go/strategies/Tribes.java @@ -8,7 +8,9 @@ import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.InterfaceDataTypeDouble; import eva2.server.go.individuals.InterfaceESIndividual; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.InterfaceHasInitRange; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -658,12 +660,12 @@ public class Tribes implements InterfaceOptimizer, java.io.Serializable { } /** - * Return a Population of TribesExplorers (AbstractEAIndividuals) of which some where + * Return a SolutionSet of TribesExplorers (AbstractEAIndividuals) of which some where * memory particles, thus the returned population is larger than the current population. * * @return a population of possible solutions. */ - public Population getAllSolutions() { + public InterfaceSolutionSet getAllSolutions() { // return population and memories? Population all = (Population)population.clone(); List mems = swarm.collectMem(); @@ -671,8 +673,10 @@ public class Tribes implements InterfaceOptimizer, java.io.Serializable { TribesPosition tp = iterator.next(); all.add(positionToExplorer(tp)); } + all.SetFunctionCalls(population.getFunctionCalls()); + all.setGenerationTo(population.getGeneration()); //all.addPopulation(pop); - return all; + return new SolutionSet(population, all); } protected TribesExplorer positionToExplorer(TribesPosition pos) { diff --git a/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java b/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java index 0518f077..f09c4b8e 100644 --- a/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java +++ b/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java @@ -9,7 +9,9 @@ import eva2.server.go.operators.archiving.InterfaceArchiving; import eva2.server.go.operators.archiving.InterfaceInformationRetrieval; import eva2.server.go.operators.moso.MOSOWeightedFitness; import eva2.server.go.operators.selection.SelectMONonDominated; +import eva2.server.go.populations.InterfaceSolutionSet; import eva2.server.go.populations.Population; +import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.AbstractMultiObjectiveOptimizationProblem; import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; @@ -286,8 +288,8 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria return "(Defunct)"; } - public Population getAllSolutions() { - return getPopulation(); + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); } /** This method allows you to set/get the optimizing technique to use. * @return The current optimizing method diff --git a/src/eva2/server/modules/Processor.java b/src/eva2/server/modules/Processor.java index ace2018c..bb4e89b2 100644 --- a/src/eva2/server/modules/Processor.java +++ b/src/eva2/server/modules/Processor.java @@ -194,7 +194,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo this.goParams.getProblem().initProblem(); this.goParams.getOptimizer().SetProblem(this.goParams.getProblem()); if (this.m_createInitialPopulations) this.goParams.getOptimizer().init(); - this.goParams.getTerminator().init(); + this.goParams.getTerminator().init(this.goParams.getProblem()); //m_Statistics.createNextGenerationPerformed((PopulationInterface)this.m_ModulParameter.getOptimizer().getPopulation()); if (m_ListenerModule!=null) m_ListenerModule.updateProgress(getStatusPercent(goParams.getOptimizer().getPopulation(), runCounter, m_Statistics.getStatisticsParameter().getMultiRuns()), null); @@ -204,26 +204,17 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo // registerPopulationStateChanged *SHOULD* be fired by the optimizer or resp. the population // as we are event listener if (popLog != null) EVAHELP.logString(this.goParams.getOptimizer().getPopulation().getIndyList(), popLog); - } while (isOptRunning() && !this.goParams.getTerminator().isTerminated(this.goParams.getOptimizer().getPopulation())); + } while (isOptRunning() && !this.goParams.getTerminator().isTerminated(this.goParams.getOptimizer().getAllSolutions())); runCounter++; //////////////// Default stats - m_Statistics.stopOptPerformed(isOptRunning()); // stop is "normal" if opt wasnt set false by the user (and thus still true) + m_Statistics.stopOptPerformed(isOptRunning(), goParams.getTerminator().lastTerminationMessage()); // stop is "normal" if opt wasnt set false by the user (and thus still true) //////////////// PP or set results without further PP if (isOptRunning()) { resultPop = performPostProcessing(); - } else resultPop = goParams.getOptimizer().getAllSolutions(); -/** - if (isOptRunning()) { - resultPop = performPostProcessing(); - //System.out.println("calling getall after PP returned " + (resultPop == null ? "null" : resultPop.size())); - } - if (resultPop == null) { - resultPop = goParams.getOptimizer().getAllSolutions(); - //System.out.println("calling getall returned " + resultPop.size()); - } -**/ + } else resultPop = goParams.getOptimizer().getAllSolutions().getSolutions(); + } setOptRunning(false); // normal finish if (m_ListenerModule!=null) m_ListenerModule.performedStop(); // is only needed in client server mode @@ -345,7 +336,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo // if textwindow was closed, check if it should be reopened for pp if (m_Statistics instanceof StatisticsWithGUI) ((StatisticsWithGUI)m_Statistics).maybeShowProxyPrinter(); } - Population resultPop = (Population)(goParams.getOptimizer().getAllSolutions()).clone(); + Population resultPop = (Population)(goParams.getOptimizer().getAllSolutions().getSolutions().clone()); if (resultPop.getFunctionCalls() != goParams.getOptimizer().getPopulation().getFunctionCalls()) { // System.err.println("bad case in Processor::performNewPostProcessing "); resultPop.SetFunctionCalls(goParams.getOptimizer().getPopulation().getFunctionCalls()); diff --git a/src/eva2/server/stat/AbstractStatistics.java b/src/eva2/server/stat/AbstractStatistics.java index 7469d658..33ecf247 100644 --- a/src/eva2/server/stat/AbstractStatistics.java +++ b/src/eva2/server/stat/AbstractStatistics.java @@ -134,7 +134,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter functionCalls = 0; } - public void stopOptPerformed(boolean normal) { + public void stopOptPerformed(boolean normal, String stopMessage) { if (TRACE) System.out.println("AbstractStatistics.stopOptPerformed"); if (runIterCnt < meanCollection.size()) { // no good: later run was shorter than the first one. What to do? Discard the longer one: @@ -143,6 +143,8 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter } optRunsPerformed++; functionCallSum += functionCalls; + if (printRunStoppedVerbosity() && (stopMessage != null)) printToTextListener(" Termination message: " + stopMessage + "\n"); + if (printRunStoppedVerbosity()) printToTextListener(" Function calls run: " + functionCalls + ", sum: " + functionCallSum + "\n"); // check for convergence if (bestCurrentIndividual != null) { if (Mathematics.norm(bestCurrentIndividual.getFitness()) < this.m_StatsParams.getConvergenceRateThreshold()) { diff --git a/src/eva2/server/stat/InterfaceStatistics.java b/src/eva2/server/stat/InterfaceStatistics.java index 1ad10794..103b28e1 100644 --- a/src/eva2/server/stat/InterfaceStatistics.java +++ b/src/eva2/server/stat/InterfaceStatistics.java @@ -30,7 +30,7 @@ public interface InterfaceStatistics { /** * Finalize statistics computations. */ - public void stopOptPerformed(boolean normal); // called from processor + public void stopOptPerformed(boolean normal, String stopMessage); // called from processor public void addTextListener(InterfaceTextListener listener); public boolean removeTextListener(InterfaceTextListener listener); public void printToTextListener(String s); diff --git a/src/eva2/server/stat/StatisticsStandalone.java b/src/eva2/server/stat/StatisticsStandalone.java index 60654d8b..4f7ddc39 100644 --- a/src/eva2/server/stat/StatisticsStandalone.java +++ b/src/eva2/server/stat/StatisticsStandalone.java @@ -125,8 +125,8 @@ public class StatisticsStandalone extends AbstractStatistics implements Interfac m_InfoString = infoString; } - public void stopOptPerformed(boolean normal) { - super.stopOptPerformed(normal); + public void stopOptPerformed(boolean normal, String stopMessage) { + super.stopOptPerformed(normal, stopMessage); if (bestCurrentIndividual != null) { m_SumOfBestFit = m_SumOfBestFit + bestCurrentIndividual.getFitness()[0]; diff --git a/src/eva2/server/stat/StatisticsWithGUI.java b/src/eva2/server/stat/StatisticsWithGUI.java index 1e221fb1..63ef6141 100644 --- a/src/eva2/server/stat/StatisticsWithGUI.java +++ b/src/eva2/server/stat/StatisticsWithGUI.java @@ -107,8 +107,8 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl m_PlotCounter = m_StatsParams.GetPlotoutput(); } - public void stopOptPerformed(boolean normal) { - super.stopOptPerformed(normal); + public void stopOptPerformed(boolean normal, String stopMessage) { + super.stopOptPerformed(normal, stopMessage); if (optRunsPerformed > m_StatsParams.getMultiRuns()) System.err.println("error: this shouldnt happen (StatisticsWithGUI::stopOptPerformed)"); // unite the graphs only if the break was "normal" diff --git a/src/wsi/ra/math/RNG.java b/src/wsi/ra/math/RNG.java index f7d2c959..ceecce73 100644 --- a/src/wsi/ra/math/RNG.java +++ b/src/wsi/ra/math/RNG.java @@ -1,5 +1,6 @@ package wsi.ra.math; +import java.util.ArrayList; import java.util.Random; import eva2.tools.Mathematics; @@ -98,6 +99,28 @@ public class RNG extends Random { } return result; } + + /** This method returns a random permutation of n int values + * @param length The number of int values + * @return The permutation [0-length-1] + */ + public static int[] randomPerm(int length) { + ArrayList intList = new ArrayList(length); + int[] result = new int[length]; + for (int i = 0; i < length; i++) { + intList.add(new Integer(i)); + } + for (int i = 0; i < length-1; i++) { + int index = randomInt(intList.size()); + result[i] = intList.get(index); + intList.remove(index); + + } + if (intList.size()>1) System.err.println("Error in randomPerm!"); + result[length-1] = intList.get(0); + return result; + } + /** * */