diff --git a/src/eva2/OptimizerRunnable.java b/src/eva2/OptimizerRunnable.java index a5528fa1..de308899 100644 --- a/src/eva2/OptimizerRunnable.java +++ b/src/eva2/OptimizerRunnable.java @@ -16,9 +16,11 @@ import eva2.server.go.populations.Population; import eva2.server.modules.GOParameters; import eva2.server.modules.Processor; import eva2.server.stat.AbstractStatistics; +import eva2.server.stat.InterfaceStatistics; import eva2.server.stat.StatisticsDummy; import eva2.server.stat.InterfaceTextListener; import eva2.server.stat.StatisticsStandalone; +import eva2.server.stat.StatsParameter; /** @@ -77,6 +79,10 @@ public class OptimizerRunnable implements Runnable { return proc.getGOParams(); } + public InterfaceStatistics getStats() { + return proc.getStatistics(); + } + public void setTextListener(InterfaceTextListener lsnr) { proc.getStatistics().removeTextListener(listener); this.listener = lsnr; @@ -175,7 +181,9 @@ public class OptimizerRunnable implements Runnable { } /** - * Set the verbosity level in the statistics module to the given value. See StatsParameter. + * Set the verbosity level in the statistics module to the given value. + * + * @see StatsParameter * @param vLev */ public void setVerbosityLevel(int vLev) { @@ -183,4 +191,35 @@ public class OptimizerRunnable implements Runnable { proc.getStatistics().getStatisticsParameter().getOutputVerbosity().setSelectedTag(vLev); } else System.err.println("Invalid verbosity leveln in OptimizerRunnable.setVerbosityLevel!"); } + + /** + * Set the output direction in the statistics module. + * + * @see StatsParameter + * @param outp + */ + public void setOutputTo(int outp) { + ((StatsParameter)proc.getStatistics().getStatisticsParameter()).setOutputTo(outp); + } + + /** + * Set the number of multiruns in the statistics module. + * @param multis + */ + public void setMultiRuns(int multis) { + ((AbstractStatistics)proc.getStatistics()).getStatisticsParameter().setMultiRuns(multis); + } + + /** + * Set the additional info output. + * @see StatsParameter + * @param addInfo + */ + public void setOutputAdditionalInfo(boolean addInfo) { + ((AbstractStatistics)proc.getStatistics()).getStatisticsParameter().setOutputAdditionalInfo(addInfo); + } + +// public void configureStats(int verbosityLevel, int outputDirection, int multiRuns, boolean additionalInfo) { +// asdf +// } } \ No newline at end of file diff --git a/src/eva2/server/go/individuals/AbstractEAIndividual.java b/src/eva2/server/go/individuals/AbstractEAIndividual.java index b93d68b0..4a4c869e 100644 --- a/src/eva2/server/go/individuals/AbstractEAIndividual.java +++ b/src/eva2/server/go/individuals/AbstractEAIndividual.java @@ -3,6 +3,7 @@ package eva2.server.go.individuals; import java.util.ArrayList; import java.util.BitSet; +import java.util.HashMap; import java.util.List; import wsi.ra.math.RNG; @@ -57,8 +58,9 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java. public double m_MutationProbability = 0.2; protected InterfaceMutation m_MutationOperator = new NoMutation(); protected InterfaceCrossover m_CrossoverOperator = new NoCrossover(); - protected String[] m_Identifiers = new String[m_ObjectIncrement]; - protected Object[] m_Objects = new Object[m_ObjectIncrement]; +// protected String[] m_Identifiers = new String[m_ObjectIncrement]; +// protected Object[] m_Objects = new Object[m_ObjectIncrement]; + protected HashMap m_dataHash = new HashMap(); public AbstractEAIndividual() { m_IDcounter++; @@ -111,8 +113,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java. */ public void cloneAEAObjects(AbstractEAIndividual individual) { // m_Name = new String(individual.m_Name); - m_Identifiers = new String[individual.m_Identifiers.length]; - m_Objects = new Object[individual.m_Identifiers.length]; + m_dataHash = (HashMap)(individual.m_dataHash.clone()); m_ConstraintViolation = individual.m_ConstraintViolation; m_AreaConst4ParallelViolated = individual.m_AreaConst4ParallelViolated; m_Marked = individual.m_Marked; @@ -122,8 +123,6 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java. parentTree = new AbstractEAIndividual[individual.parentTree.length]; for (int i=0; i sortedArr = null; - private int lastQModCount = -1; transient protected InterfacePopulationChangedEventListener m_Listener = null; + + // the evaluation interval at which listeners are notified protected int notifyEvalInterval = 0; protected HashMap additionalPopData = null; @@ -45,6 +48,13 @@ public class Population extends ArrayList implements PopulationInterface, Clonea boolean useHistory = false; public ArrayList m_History = new ArrayList(); + // remember when the last sorted queue was prepared + private int lastQModCount = -1; + // remember when the last evaluation was performed + private Pair evaluationTimeHashes = null; + // remember when the last evaluation was performed + private int evaluationTimeModCount = -1; + public Population() { } @@ -129,6 +139,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea this.m_History = new ArrayList(); this.m_Generation = 0; this.m_FunctionCalls = 0; + evaluationTimeHashes = null; + evaluationTimeModCount = -1; if (this.m_Archive != null) { this.m_Archive.clear(); this.m_Archive.init(); @@ -178,7 +190,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea * * @param d The number of function calls to increment. */ - public void incrFunctionCallsby(int d) { + public void incrFunctionCallsBy(int d) { if (doEvalNotify()) { // System.out.println("checking funcall event..."); int nextStep; // next interval boundary @@ -271,7 +283,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea } /** - * Resets the fitness to the maximum possible value for the given individual. + * Resets the fitnes to the maximum possible value for the given individual. * * @param indy an individual whose fitness will be reset */ @@ -915,4 +927,39 @@ public class Population extends ArrayList implements PopulationInterface, Clonea public void setNotifyEvalInterval(int notifyEvalInterval) { this.notifyEvalInterval = notifyEvalInterval; } + + /** + * Check whether the population at the current state has been marked as + * evaluated. This allows to avoid double evaluations. + * + * @return true if the population has been marked as evaluated in its current state, else false + */ + public boolean isEvaluated() { + Pair hashes = getIndyHashSums(); + + if (evaluationTimeHashes == null) return false; + else return (hashes.head()==evaluationTimeHashes.head() && (hashes.tail() == evaluationTimeHashes.tail()) && (evaluationTimeModCount == modCount)); + } + + /** + * Mark the population at the current state as evaluated. Changes to the modCount or hashes of individuals + * will invalidate the mark. + * + * @see isEvaluated() + */ + public void setEvaluated() { + evaluationTimeModCount = modCount; + evaluationTimeHashes = getIndyHashSums(); + } + + private Pair getIndyHashSums() { + int hashSum = 0, hashSumAbs = 0; + int hash; + for (int i=0; i1) && (meanCollection != null)) { if (printFinalVerbosity()) printToTextListener("Averaged performance:\n"); for (int i=0; i getPlotDescriptions() { - ArrayList desc = new ArrayList(); - switch (getPlotData().getSelectedTagID()) { - case StatsParameter.PLOT_BEST_AND_WORST: - desc.add(new String[] {"Best", "Worst"}); - break; - case StatsParameter.PLOT_BEST: - desc.add(new String[] {"Best"}); - break; - case StatsParameter.PLOT_WORST: - desc.add(new String[] {"Worst"}); - break; - case StatsParameter.PLOT_BEST_AND_MEASURES: - desc.add(new String[] {"Best", "AvgDist", "MaxDist"}); - break; - } - return desc; - } - - /** - * - */ - public void saveInstance() { - Serializer.storeObject("Statistics.ser", this); - } + /** + * + */ + public static StatsParameter getInstance() { + StatsParameter Instance = (StatsParameter) Serializer.loadObject("Statistics.ser"); + if (Instance == null) + Instance = new StatsParameter(); + return Instance; + } - /** - * - */ - private StatsParameter(StatsParameter Source) { - m_ConvergenceRateThreshold = Source.m_ConvergenceRateThreshold; - m_useStatPlot = Source.m_useStatPlot; - m_Textoutput = Source.m_Textoutput; - m_Plotoutput = Source.m_Plotoutput; - m_PlotFitness = Source.m_PlotFitness; - m_MultiRuns = Source.m_MultiRuns; - m_ResultFilePrefix = Source.m_ResultFilePrefix; - verboK = Source.verboK; - } + /** + * + */ + public StatsParameter() { + m_Name = "Statistics"; + outputVerbosity.setSelectedTag(2); + outputTo.setSelectedTag(1); + } - /** - * - */ - public Object getClone() { - return new StatsParameter(this); - } + /** + * + */ + public String toString() { + String ret = "\r\nStatParameter:\r\nm_MultiRuns=" + m_MultiRuns + + "\r\nm_Textoutput=" + m_Textoutput + + "\r\nm_Plotoutput=" + m_Plotoutput; + return ret; + } - /** - * - */ - public String getName() { - return m_Name; - } + /** + * Return a list of String arrays describing the selected plot options, e.g. {"Best"} or {"Best", "Worst"}. + * For now, only one array is returned. + * + * @return a list of String arrays describing the selected plot options + */ + public ArrayList getPlotDescriptions() { + ArrayList desc = new ArrayList(); + switch (getPlotData().getSelectedTagID()) { + case StatsParameter.PLOT_BEST_AND_WORST: + desc.add(new String[] {"Best", "Worst"}); + break; + case StatsParameter.PLOT_BEST: + desc.add(new String[] {"Best"}); + break; + case StatsParameter.PLOT_WORST: + desc.add(new String[] {"Worst"}); + break; + case StatsParameter.PLOT_BEST_AND_MEASURES: + desc.add(new String[] {"Best", "AvgDist", "MaxDist"}); + break; + } + return desc; + } - public String globalInfo() { - return "Configure statistics and output of the optimization run."; - } + /** + * + */ + public void saveInstance() { + Serializer.storeObject("Statistics.ser", this); + } - /** - * - */ - public void setPlotoutput(int i) { - m_Plotoutput = i; - } + /** + * + */ + private StatsParameter(StatsParameter Source) { + m_ConvergenceRateThreshold = Source.m_ConvergenceRateThreshold; + m_useStatPlot = Source.m_useStatPlot; + m_Textoutput = Source.m_Textoutput; + m_Plotoutput = Source.m_Plotoutput; + m_PlotFitness = Source.m_PlotFitness; + m_MultiRuns = Source.m_MultiRuns; + m_ResultFilePrefix = Source.m_ResultFilePrefix; + verboK = Source.verboK; + } - /** - * - */ - public int GetPlotoutput() { - return m_Plotoutput; - } + /** + * + */ + public Object getClone() { + return new StatsParameter(this); + } -// /** -// * -// */ -// public String plotFrequencyTipText() { -// return "Frequency how often the fitness plot gets an update. plotoutput=1 -> there is a output every generation. plotoutput<0 -> there is no plot output"; -// } + /** + * + */ + public String getName() { + return m_Name; + } -// /** -// * -// */ -// public String printMeanTipText() { -// return "Prints the mean of the fitness plot. Makes only sense when multiRuns > 1;"; -// } + public String globalInfo() { + return "Configure statistics and output of the optimization run."; + } - /** - * - */ - public void setMultiRuns(int x) { - m_MultiRuns = x; - } + /** + * + */ + public void setPlotoutput(int i) { + m_Plotoutput = i; + } - /** - * - */ - public int getMultiRuns() { - return m_MultiRuns; - } + /** + * + */ + public int GetPlotoutput() { + return m_Plotoutput; + } - /** - * - */ - public String multiRunsTipText() { - return "Number of independent optimization runs to evaluate."; - } - - /** - * - */ - public String GetInfoString() { - return m_InfoString; - } - - /** - * - */ - public void setInfoString(String s) { - m_InfoString = s; - } - - /** - * - */ - public String infoStringTipText() { - return "Infostring displayed on fitness graph by prssing the right mouse button."; - } - - /** - * - */ - public boolean GetuseStatPlot() { - return m_useStatPlot; - } - - /** - * - */ - public void setuseStatPlot(boolean x) { - m_useStatPlot = x; - } - - /** - * - */ - public String useStatPlotTipText() { - return "Plotting each fitness graph separate if multiruns > 1."; - } - - /** - * - */ - public SelectedTag getPlotData() { - return new SelectedTag(m_PlotFitness, TAGS_PLOT_FITNESS); - } - - /** - * - */ - public void setPlotData(SelectedTag newMethod) { - m_PlotFitness = newMethod.getSelectedTag().getID(); - } - - /** - * - */ - public String plotDataTipText() { - return "The data to be plotted: best fitness, worst fitness or average/max distance in population."; - } - -// /** -// * -// */ -// public String plotObjectivesTipText() { -// return "The individual of which the objectives are plotted."; -// } - - - /** - * - */ - public void SetResultFilePrefix(String x) { - if (x==null) m_ResultFilePrefix = ""; - else m_ResultFilePrefix = x; - } - - /** - * - */ - public String getResultFilePrefix() { - return m_ResultFilePrefix; - } - - public void SetShowTextOutput(boolean show) { - // activate if not activated - if (show && outputTo.getSelectedTagID() == 0) outputTo.setSelectedTag(2); - // deactivate if activated - else if (!show && outputTo.getSelectedTagID()>0) outputTo.setSelectedTag(0); - } - - public boolean isShowTextOutput() { - return outputTo.getSelectedTagID()>0; - } -// -// /** -// * -// */ -// public String resultFileNameTipText() { -// return "File name for the result file. If empty or 'none', no output file will be created."; -// } - - public String convergenceRateThresholdTipText() { - return "Provided the optimal fitness is at zero, give the threshold below which it is considered as 'reached'"; - } - - /** - * - * @param x - */ - public void setConvergenceRateThreshold(double x) { - m_ConvergenceRateThreshold = x; - } - - /** - * - */ - public double getConvergenceRateThreshold() { - return m_ConvergenceRateThreshold; - } - // /** -// * @return the showOutputData -// */ +// * +// */ +// public String plotFrequencyTipText() { +// return "Frequency how often the fitness plot gets an update. plotoutput=1 -> there is a output every generation. plotoutput<0 -> there is no plot output"; +// } + +// /** +// * +// */ +// public String printMeanTipText() { +// return "Prints the mean of the fitness plot. Makes only sense when multiRuns > 1;"; +// } + + /** + * + */ + public void setMultiRuns(int x) { + m_MultiRuns = x; + } + + /** + * + */ + public int getMultiRuns() { + return m_MultiRuns; + } + + /** + * + */ + public String multiRunsTipText() { + return "Number of independent optimization runs to evaluate."; + } + + /** + * + */ + public String GetInfoString() { + return m_InfoString; + } + + /** + * + */ + public void setInfoString(String s) { + m_InfoString = s; + } + + /** + * + */ + public String infoStringTipText() { + return "Infostring displayed on fitness graph by prssing the right mouse button."; + } + + /** + * + */ + public boolean GetuseStatPlot() { + return m_useStatPlot; + } + + /** + * + */ + public void setuseStatPlot(boolean x) { + m_useStatPlot = x; + } + + /** + * + */ + public String useStatPlotTipText() { + return "Plotting each fitness graph separate if multiruns > 1."; + } + + /** + * + */ + public SelectedTag getPlotData() { + return new SelectedTag(m_PlotFitness, TAGS_PLOT_FITNESS); + } + + /** + * + */ + public void setPlotData(SelectedTag newMethod) { + m_PlotFitness = newMethod.getSelectedTag().getID(); + } + + /** + * + */ + public String plotDataTipText() { + return "The data to be plotted: best fitness, worst fitness or average/max distance in population."; + } + +// /** +// * +// */ +// public String plotObjectivesTipText() { +// return "The individual of which the objectives are plotted."; +// } + + + /** + * + */ + public void SetResultFilePrefix(String x) { + if (x==null) m_ResultFilePrefix = ""; + else m_ResultFilePrefix = x; + } + + /** + * + */ + public String getResultFilePrefix() { + return m_ResultFilePrefix; + } + + public void SetShowTextOutput(boolean show) { + // activate if not activated + if (show && outputTo.getSelectedTagID() == 0) outputTo.setSelectedTag(2); + // deactivate if activated + else if (!show && outputTo.getSelectedTagID()>0) outputTo.setSelectedTag(0); + } + + public boolean isShowTextOutput() { + return outputTo.getSelectedTagID()>0; + } + +// /** +// * +// */ +// public String resultFileNameTipText() { +// return "File name for the result file. If empty or 'none', no output file will be created."; +// } + + public String convergenceRateThresholdTipText() { + return "Provided the optimal fitness is at zero, give the threshold below which it is considered as 'reached'"; + } + + /** + * + * @param x + */ + public void setConvergenceRateThreshold(double x) { + m_ConvergenceRateThreshold = x; + } + + /** + * + */ + public double getConvergenceRateThreshold() { + return m_ConvergenceRateThreshold; + } + +// /** +// * @return the showOutputData +// */ // public boolean isShowTextOutput() { -// return showTextOutput; +// return showTextOutput; // } -// + // /** -// * -// * @param showOutputData the showOutputData to set -// */ +// * +// * @param showOutputData the showOutputData to set +// */ // public void setShowTextOutput(boolean bShow) { -// this.showTextOutput = bShow; +// this.showTextOutput = bShow; // } -// + // public String showTextOutputTipText() { -// return "Indicates whether further text output should be printed"; +// return "Indicates whether further text output should be printed"; // } public boolean isOutputAdditionalInfo() { @@ -350,38 +354,45 @@ public class StatsParameter implements InterfaceStatisticsParameter, Serializabl public void setOutputAdditionalInfo(boolean showAdd) { showAdditionalProblemInfo = showAdd; } - + public String outputAdditionalInfoTipText() { return "Activate to output additional problem information per iteration, such as the current solution representation."; } - + public void hideHideable() { setOutputVerbosity(getOutputVerbosity()); } - public void setOutputVerbosity(SelectedTag sTag) { - outputVerbosity = sTag; - GenericObjectEditor.setHideProperty(this.getClass(), "outputVerbosityK", sTag.getSelectedTagID() != VERBOSITY_KTH_IT); - } - public SelectedTag getOutputVerbosity() { - return outputVerbosity; - } + + public void setOutputVerbosity(SelectedTag sTag) { + outputVerbosity = sTag; + GenericObjectEditor.setHideProperty(this.getClass(), "outputVerbosityK", sTag.getSelectedTagID() != VERBOSITY_KTH_IT); + } + + public void setOutputVerbosity(int i) { + outputVerbosity.setSelectedTag(i); + GenericObjectEditor.setHideProperty(this.getClass(), "outputVerbosityK", outputVerbosity.getSelectedTagID() != VERBOSITY_KTH_IT); + } + + public SelectedTag getOutputVerbosity() { + return outputVerbosity; + } + + public String outputVerbosityTipText() { + return "Set the data output level."; + } + + public int getOutputVerbosityK() { + return verboK; + } + + public void setOutputVerbosityK(int k) { + verboK = k; + } + + public String outputVerbosityKTipText() { + return "Set the interval of data output for intermediate verbosity (in generations)."; + } - public String outputVerbosityTipText() { - return "Set the data output level."; - } - - public int getOutputVerbosityK() { - return verboK; - } - - public void setOutputVerbosityK(int k) { - verboK = k; - } - - public String outputVerbosityKTipText() { - return "Set the interval of data output for intermediate verbosity (in generations)."; - } - public SelectedTag getOutputTo() { return outputTo; } @@ -389,9 +400,13 @@ public class StatsParameter implements InterfaceStatisticsParameter, Serializabl public void setOutputTo(SelectedTag tag) { outputTo = tag; } - + + public void setOutputTo(int i) { + outputTo.setSelectedTag(i); + } + public String outputToTipText() { return "Set the output destination; to deactivate output, set verbosity to none."; } - + } \ No newline at end of file diff --git a/src/eva2/tools/Pair.java b/src/eva2/tools/Pair.java index 2dd5aba4..52a87c49 100644 --- a/src/eva2/tools/Pair.java +++ b/src/eva2/tools/Pair.java @@ -1,12 +1,18 @@ package eva2.tools; +import java.io.Serializable; + /** * Simple pair structure of two types, Scheme style, but typed. * * @author mkron * */ -public class Pair { +public class Pair implements Serializable { + /** + * + */ + private static final long serialVersionUID = -3620465393975181451L; public S head; public T tail;