diff --git a/src/eva2/server/go/operators/postprocess/PostProcess.java b/src/eva2/server/go/operators/postprocess/PostProcess.java index 834fab71..b76dc476 100644 --- a/src/eva2/server/go/operators/postprocess/PostProcess.java +++ b/src/eva2/server/go/operators/postprocess/PostProcess.java @@ -35,8 +35,10 @@ import eva2.server.go.problems.AbstractMultiModalProblemKnown; import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.Interface2DBorderProblem; +import eva2.server.go.problems.InterfaceHasSolutionViewer; import eva2.server.go.problems.InterfaceInterestingHistogram; import eva2.server.go.problems.InterfaceMultimodalProblemKnown; +import eva2.server.go.problems.InterfaceSolutionViewer; import eva2.server.go.strategies.EvolutionStrategies; import eva2.server.go.strategies.GradientDescentAlgorithm; import eva2.server.go.strategies.HillClimbing; @@ -754,13 +756,12 @@ public class PostProcess { if (indy instanceof InterfaceDataTypeDouble || (indy instanceof InterfaceESIndividual)) { if (indy instanceof InterfaceESIndividual) ((InterfaceESIndividual)indy).SetDGenotype(data); else ((InterfaceDataTypeDouble)indy).SetDoubleGenotype(data); - } + } else throw new RuntimeException("Error, unable to set double data to individual instance " + indy.getClass() + " in PostProcess.setDoubleData"); } /** * Create a population of clones of the given individual in a sub range around the individual. - * The given individual must be double compliant. The population size is determined by the range dimension - * using the formula for lambda=4+3*log(dim). + * The given individual must be double compliant. * The individuals are randomly initialized in a box of side length searchBoxLen around indy holding the * problem constraints, meaning that the box may be smaller at the brim of the problem-defined search range. * @@ -769,8 +770,7 @@ public class PostProcess { * @return */ public static void createPopInSubRange(Population destPop, double searchBoxLen, - int targetSize, - AbstractEAIndividual indy) { + int targetSize, AbstractEAIndividual indy) { if (isDoubleCompliant(indy)) { double[][] range = getDoubleRange(indy); double[] data = getDoubleData(indy); @@ -783,11 +783,7 @@ public class PostProcess { // Population pop = new Population(); destPop.clear(); for (int i=0; i1) { if (listener != null) listener.println("measures: " + BeanInspector.toString(outputPop.getPopulationMeasures())); + if (listener != null) listener.println("pop.metric: " + BeanInspector.toString(outputPop.getPopMetric())); if (listener != null) listener.println("solution histogram: " + solHist + ", score " + solHist.getScore()); if ((listener != null) && (problem instanceof InterfaceInterestingHistogram)) { SolutionHistogram pSolHist = ((InterfaceInterestingHistogram)problem).getHistogram(); @@ -1075,17 +1089,118 @@ public class PostProcess { //////////// multimodal data output evaluateMultiModal(outputPop, problem, listener); - Population nBestPop = outputPop.getBestNIndividuals(params.getPrintNBest(), -1); // n individuals are returned and sorted, all of them if n<=0 - if (listener != null) listener.println("Best after post process:" + ((outputPop.size()>nBestPop.size()) ? ( " (first " + nBestPop.size() + " of " + outputPop.size() + ")") : (" (" + nBestPop.size() + ")") )); - //////////// output some individual data - if (listener != null) for (int i=0; i0) ? params.getPrintNBest() : nBestPop.size()); + printK = Math.min(printK, nBestPop.size()); + if (listener != null) listener.println("Best after post process:" + " (first " + printK + " of " + outputPop.size() + ")"); +// ((outputPop.size()>nBestPop.size()) +// ? ( " (first " + nBestPop.size() + " of " + outputPop.size() + ")") : +// (" (" + nBestPop.size() + ")") )); + //////////// output some individual data + if (listener != null) for (int i=0; i 0) { + if (listener!=null) listener.print(" measures fit: "); + int critCnt = extrOpts.getEAIndividual(0).getFitness().length; + for (int i=0; i1) { + if (listener!=null) listener.print("; phen: " + BeanInspector.toString(extrOpts.getPopulationMeasures(new PhenotypeMetric()))); + if (listener!=null) listener.print("; eucl: " + BeanInspector.toString(extrOpts.getPopulationMeasures(new EuclideanMetric()))); + if (listener!=null) listener.print("; popMetric: " + BeanInspector.toString(extrOpts.getPopulationMeasures())); + } + if (listener!=null) listener.println(""); +// listener.println(" correlations of all (min,max,avg,med,var): "+ BeanInspector.toString(extrOpts.getCorrelations())); + for (int i=16; i>2; i/=2) { + Population bestN = extrOpts.getBestNIndividuals(i, -1); + listener.println(" phen. measures of top " + bestN.size() + ": " + BeanInspector.toString(bestN.getPopulationMeasures(new PhenotypeMetric()))); +// ClusteringKMeans km = new ClusteringKMeans(); km.setK(2); +// km.initClustering(bestN); +// Population[] clusts = km.cluster(bestN, bestN); +// System.out.println("cluster sizes: " + clusts[0].size() + " " + clusts[1].size() + " " + clusts[2].size()); +// listener.println(" correlations of top " + bestN.size() + ": " + BeanInspector.toString(bestN.getCorrelations())); + } + } + } + + return foundOpts; + } + /** * Select a local search range for a given method based on the clustering parameter. * If clustering was deactivated (sigma <= 0), then the default mutation step size is used. diff --git a/src/eva2/server/go/operators/postprocess/PostProcessParams.java b/src/eva2/server/go/operators/postprocess/PostProcessParams.java index 9a7e3eca..75019e94 100644 --- a/src/eva2/server/go/operators/postprocess/PostProcessParams.java +++ b/src/eva2/server/go/operators/postprocess/PostProcessParams.java @@ -13,6 +13,10 @@ public class PostProcessParams implements InterfacePostProcessParams, Serializab protected double postProcessClusterSigma = 0.05; protected int printNBest = 10; protected PostProcessMethod method = PostProcessMethod.nelderMead; + protected double[] accuracies = new double[]{0.01, 0.001, 0.0001}; + protected double accAssumeConv = 1e-8; + protected int accMaxEval = -1; + private boolean withPlot = false; public PostProcessParams() { @@ -77,6 +81,9 @@ public class PostProcessParams implements InterfacePostProcessParams, Serializab GenericObjectEditor.setShowProperty(this.getClass(), "printNBest", postProcess); GenericObjectEditor.setShowProperty(this.getClass(), "PPMethod", postProcess); GenericObjectEditor.setShowProperty(this.getClass(), "withPlot", postProcess); + GenericObjectEditor.setShowProperty(this.getClass(), "accuracies", postProcess); + GenericObjectEditor.setShowProperty(this.getClass(), "accAssumeConv", postProcess); + GenericObjectEditor.setShowProperty(this.getClass(), "accMaxEval", postProcess); } public String doPostProcessingTipText() { return "Toggle post processing of the solutions."; @@ -123,17 +130,16 @@ public class PostProcessParams implements InterfacePostProcessParams, Serializab } public static String globalInfo() { - return "Combined clustering and hill-climbing for post-processing of solutions."; + return "Combined clustering and local search post-processing of solutions. Additionally, accuracy checks can be performed on the " + + "returned solutions with different thresholds."; } public PostProcessMethod getPPMethod() { return method; } - public String PPMethodTipText() { return "The method to use for post-processing."; } - public void setPPMethod(PostProcessMethod meth) { method=meth; } @@ -141,8 +147,39 @@ public class PostProcessParams implements InterfacePostProcessParams, Serializab public boolean isWithPlot() { return withPlot; } - public void setWithPlot(boolean withPlot) { this.withPlot = withPlot; } + + public double[] getAccuracies() { + return accuracies; + } + public void setAccuracies(double[] accuracies) { + this.accuracies = accuracies; + } + public String accuraciesTipText() { + return "The accuracy thresholds to be tested"; + } + + public double getAccAssumeConv() { + return accAssumeConv; + } + public void setAccAssumeConv(double accAssumeConv) { + this.accAssumeConv = accAssumeConv; + } + public String accAssumeConvTipText() { + return "The local search refinement is stopped earlier if the fitness changes less than this value"; + } + + public int getAccMaxEval() { + return accMaxEval; + } + public void setAccMaxEval(int accMaxEval) { + this.accMaxEval = accMaxEval; + } + public String accMaxEvalTipText() { + return "The maximal number of evaluations (times dimension) for accuracy check or -1 to use the default."; + } + + } diff --git a/src/eva2/server/go/operators/postprocess/SolutionHistogram.java b/src/eva2/server/go/operators/postprocess/SolutionHistogram.java index e23b6c70..de49c619 100644 --- a/src/eva2/server/go/operators/postprocess/SolutionHistogram.java +++ b/src/eva2/server/go/operators/postprocess/SolutionHistogram.java @@ -4,6 +4,8 @@ import java.util.Arrays; import eva2.gui.BeanInspector; import eva2.server.go.populations.Population; +import eva2.server.go.problems.AbstractOptimizationProblem; +import eva2.server.go.problems.InterfaceInterestingHistogram; import eva2.tools.math.Mathematics; public class SolutionHistogram { @@ -100,12 +102,28 @@ public class SolutionHistogram { */ public static void createFitNormHistogram(Population pop, SolutionHistogram hist, int crit) { hist.reset(); - for (int i=0; i0) { + if (pop.getBestFitness()[crit]