Load and store Optimizations as YAML.

refs #31
- Introduces custom BeanSerializer using SnakeYAML
- Removed previous json package
- Introduces eva2.yaml package
- Hidden properties are not saved
- Reintroduces output in text window
This commit is contained in:
Fabian Becker 2014-11-02 17:53:42 +01:00
parent 173ebd67c6
commit 551b14fe3d
11 changed files with 102 additions and 65 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
/build/ /build/
out/ out/
*.ser *.ser
*.yml
.settings/ .settings/
.project .project
.classpath .classpath

View File

@ -1,4 +0,0 @@
/**
* JSON package for serializing and deserializing optimization configurations.
*/
package eva2.json;

View File

@ -3,18 +3,18 @@ package eva2.optimization.modules;
import eva2.gui.BeanInspector; import eva2.gui.BeanInspector;
import eva2.optimization.go.InterfaceNotifyOnInformers; import eva2.optimization.go.InterfaceNotifyOnInformers;
import eva2.optimization.go.InterfaceOptimizationParameters; import eva2.optimization.go.InterfaceOptimizationParameters;
import eva2.optimization.population.InterfacePopulationChangedEventListener;
import eva2.optimization.operator.postprocess.InterfacePostProcessParams; import eva2.optimization.operator.postprocess.InterfacePostProcessParams;
import eva2.optimization.operator.postprocess.PostProcessParams; import eva2.optimization.operator.postprocess.PostProcessParams;
import eva2.optimization.operator.terminators.InterfaceTerminator; import eva2.optimization.operator.terminators.InterfaceTerminator;
import eva2.optimization.population.InterfacePopulationChangedEventListener;
import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.problems.InterfaceAdditionalPopulationInformer; import eva2.problems.InterfaceAdditionalPopulationInformer;
import eva2.problems.InterfaceOptimizationProblem; import eva2.problems.InterfaceOptimizationProblem;
import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.tools.Serializer;
import eva2.util.annotation.Parameter; import eva2.util.annotation.Parameter;
import eva2.yaml.BeanSerializer;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -121,15 +121,17 @@ public abstract class AbstractOptimizationParameters implements InterfaceOptimiz
public void saveInstance(String fileName) { public void saveInstance(String fileName) {
try { try {
FileOutputStream fileStream = new FileOutputStream(fileName); FileOutputStream fileStream = new FileOutputStream(fileName);
Serializer.storeObject(fileStream, this); String yaml = BeanSerializer.serializeObject(this);
} catch (FileNotFoundException ex) { fileStream.write(yaml.getBytes());
fileStream.close();
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "Could not store instance object.", ex); LOGGER.log(Level.WARNING, "Could not store instance object.", ex);
} }
} }
@Override @Override
public void saveInstance() { public void saveInstance() {
String fileName = this.getClass().getSimpleName() + ".ser"; String fileName = this.getClass().getSimpleName() + ".yml";
saveInstance(fileName); saveInstance(fileName);
} }

View File

@ -4,12 +4,11 @@ import eva2.optimization.go.InterfaceOptimizationParameters;
import eva2.optimization.operator.terminators.EvaluationTerminator; import eva2.optimization.operator.terminators.EvaluationTerminator;
import eva2.optimization.operator.terminators.InterfaceTerminator; import eva2.optimization.operator.terminators.InterfaceTerminator;
import eva2.optimization.strategies.DifferentialEvolution; import eva2.optimization.strategies.DifferentialEvolution;
import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.problems.F1Problem; import eva2.problems.F1Problem;
import eva2.problems.InterfaceOptimizationProblem; import eva2.problems.InterfaceOptimizationProblem;
import eva2.optimization.strategies.GeneticAlgorithm;
import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.tools.Serializer;
import eva2.util.annotation.Description; import eva2.util.annotation.Description;
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -35,21 +34,21 @@ public class OptimizationParameters extends AbstractOptimizationParameters imple
* @return * @return
*/ */
public static OptimizationParameters getInstance() { public static OptimizationParameters getInstance() {
return getInstance("OptimizationParameters.ser", true); return getInstance("OptimizationParameters.yml", true);
} }
/** /**
* Create an instance from a given serialized parameter file. * Create an instance from a given serialized parameter file.
* *
* @param serParamFile Serialized Parameter File * @param yamlFile Serialized Parameter File
* @param casually if true, standard parameters are used quietly if the params cannot be loaded * @param casually if true, standard parameters are used quietly if the params cannot be loaded
* @return a OptimizationParameters instance * @return a OptimizationParameters instance
*/ */
public static OptimizationParameters getInstance(String serParamFile, final boolean casually) { public static OptimizationParameters getInstance(String yamlFile, final boolean casually) {
OptimizationParameters instance = null; OptimizationParameters instance = null;
try { try {
FileInputStream fileStream = new FileInputStream(serParamFile); FileInputStream fileStream = new FileInputStream(yamlFile);
instance = (OptimizationParameters) Serializer.loadObject(fileStream, casually); instance = (OptimizationParameters) new Yaml().load(fileStream);
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
LOGGER.log(Level.WARNING, "Could not load instance object.", ex); LOGGER.log(Level.WARNING, "Could not load instance object.", ex);
} }

View File

@ -4,7 +4,6 @@ import eva2.gui.BeanInspector;
import eva2.optimization.OptimizationStateListener; import eva2.optimization.OptimizationStateListener;
import eva2.optimization.go.InterfaceNotifyOnInformers; import eva2.optimization.go.InterfaceNotifyOnInformers;
import eva2.optimization.go.InterfaceOptimizationParameters; import eva2.optimization.go.InterfaceOptimizationParameters;
import eva2.optimization.population.InterfacePopulationChangedEventListener;
import eva2.optimization.operator.paramcontrol.ConstantParameters; import eva2.optimization.operator.paramcontrol.ConstantParameters;
import eva2.optimization.operator.paramcontrol.InterfaceParameterControl; import eva2.optimization.operator.paramcontrol.InterfaceParameterControl;
import eva2.optimization.operator.postprocess.PostProcess; import eva2.optimization.operator.postprocess.PostProcess;
@ -12,13 +11,14 @@ import eva2.optimization.operator.postprocess.PostProcessParams;
import eva2.optimization.operator.terminators.EvaluationTerminator; import eva2.optimization.operator.terminators.EvaluationTerminator;
import eva2.optimization.operator.terminators.GenerationTerminator; import eva2.optimization.operator.terminators.GenerationTerminator;
import eva2.optimization.operator.terminators.InterfaceTerminator; import eva2.optimization.operator.terminators.InterfaceTerminator;
import eva2.optimization.population.InterfacePopulationChangedEventListener;
import eva2.optimization.population.Population; import eva2.optimization.population.Population;
import eva2.problems.AbstractOptimizationProblem;
import eva2.problems.InterfaceAdditionalPopulationInformer;
import eva2.optimization.statistics.InterfaceStatistics; import eva2.optimization.statistics.InterfaceStatistics;
import eva2.optimization.statistics.InterfaceTextListener; import eva2.optimization.statistics.InterfaceTextListener;
import eva2.optimization.statistics.StatisticsWithGUI; import eva2.optimization.statistics.StatisticsWithGUI;
import eva2.optimization.strategies.InterfaceOptimizer; import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.problems.AbstractOptimizationProblem;
import eva2.problems.InterfaceAdditionalPopulationInformer;
import eva2.problems.InterfaceOptimizationProblem; import eva2.problems.InterfaceOptimizationProblem;
import eva2.tools.EVAERROR; import eva2.tools.EVAERROR;
import eva2.tools.StringTools; import eva2.tools.StringTools;
@ -48,7 +48,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
private InterfaceStatistics statistics; private InterfaceStatistics statistics;
private InterfaceOptimizationParameters optimizationParameters; private InterfaceOptimizationParameters optimizationParameters;
private boolean createInitialPopulations = true; private boolean createInitialPopulations = true;
private boolean saveParams = false; private boolean saveParams = true;
private OptimizationStateListener optimizationStateListener; private OptimizationStateListener optimizationStateListener;
private boolean wasRestarted = false; private boolean wasRestarted = false;
private int runCounter = 0; private int runCounter = 0;
@ -167,7 +167,6 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
EVAERROR.clearMsgCache(); EVAERROR.clearMsgCache();
while (isOptimizationRunning()) { while (isOptimizationRunning()) {
setPriority(3); setPriority(3);
// ToDo: Do we need this really?
if (saveParams) { if (saveParams) {
try { try {
optimizationParameters.saveInstance(); optimizationParameters.saveInstance();

View File

@ -12,6 +12,7 @@ import eva2.tools.StringSelection;
import eva2.tools.StringTools; import eva2.tools.StringTools;
import eva2.tools.ToolBox; import eva2.tools.ToolBox;
import eva2.tools.math.Mathematics; import eva2.tools.math.Mathematics;
import eva2.yaml.BeanSerializer;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -195,7 +196,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
* *
* @param infoString * @param infoString
*/ */
protected void initOutput(String infoString) { protected void initializeOutput(String infoString) {
String startDate = getDateString(); String startDate = getDateString();
// open the result file: // open the result file:
if (doFileOutput() // not "text-window only" if (doFileOutput() // not "text-window only"
@ -271,15 +272,11 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
if (saveParams) { if (saveParams) {
statisticsParameter.saveInstance(); statisticsParameter.saveInstance();
} }
initOutput(infoString); initializeOutput(infoString);
bestIndyAllRuns = null; bestIndyAllRuns = null;
bestFeasibleAllRuns = null; bestFeasibleAllRuns = null;
// meanBestOfRunFitness = null;
// meanBestFeasibleFit = null;
runBestFeasibleList = new ArrayList<>(); runBestFeasibleList = new ArrayList<>();
runBestFitList = new ArrayList<>(); runBestFitList = new ArrayList<>();
// if (refineMultiRuns) meanCollection = new ArrayList<double[][]>();
// else meanCollection = null;
if (refineMultiRuns) { if (refineMultiRuns) {
sumDataCollection = new ArrayList<>(); sumDataCollection = new ArrayList<>();
} else { } else {
@ -289,7 +286,6 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
finalObjectData = null; finalObjectData = null;
statDataSumOverAll = null; statDataSumOverAll = null;
// lastAdditionalInfoSums = null;
feasibleFoundAfterSum = -1; feasibleFoundAfterSum = -1;
numOfRunsFeasibleFound = 0; numOfRunsFeasibleFound = 0;
@ -305,14 +301,14 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
if (printRunIntroVerbosity()) { if (printRunIntroVerbosity()) {
printToTextListener("\n****** Multirun " + runNumber); printToTextListener("\n****** Multirun " + runNumber);
} }
/*
ToDo: Figure out if we need this. Right now it is just spamming the text output
if (params != null) { if (params != null) {
if (printRunIntroVerbosity()) { if (printRunIntroVerbosity()) {
printToTextListener("\nOptimization parameters: "); printToTextListener("\nOptimization parameters: \n");
printToTextListener(BeanInspector.niceToString(params)); printToTextListener(BeanSerializer.serializeObject(params));
} }
} }
/*
ToDo: Figure out if we need this. Right now it is just spamming the text output
if (printRunIntroVerbosity()) { if (printRunIntroVerbosity()) {
printToTextListener("\nStatistics parameters: "); printToTextListener("\nStatistics parameters: ");
printToTextListener(BeanInspector.niceToString(getStatisticsParameter()) + '\n'); printToTextListener(BeanInspector.niceToString(getStatisticsParameter()) + '\n');

View File

@ -9,6 +9,7 @@ import eva2.tools.SelectedTag;
import eva2.tools.Serializer; import eva2.tools.Serializer;
import eva2.tools.StringSelection; import eva2.tools.StringSelection;
import eva2.util.annotation.Description; import eva2.util.annotation.Description;
import eva2.util.annotation.Parameter;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -31,7 +32,6 @@ import java.util.logging.Logger;
*/ */
@Description(value = "Configure statistics and output of the optimization run. Changes to the data selection state will not take effect during a run.") @Description(value = "Configure statistics and output of the optimization run. Changes to the data selection state will not take effect during a run.")
public class StatisticsParameters implements InterfaceStatisticsParameters, InterfaceNotifyOnInformers, Serializable { public class StatisticsParameters implements InterfaceStatisticsParameters, InterfaceNotifyOnInformers, Serializable {
private static final long serialVersionUID = -8681061379203108390L;
private static final Logger LOGGER = Logger.getLogger(StatisticsParameters.class.getName()); private static final Logger LOGGER = Logger.getLogger(StatisticsParameters.class.getName());
public final static int VERBOSITY_NONE = 0; public final static int VERBOSITY_NONE = 0;
public final static int VERBOSITY_FINAL = 1; public final static int VERBOSITY_FINAL = 1;
@ -169,13 +169,6 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
return "Number of independent optimization runs to evaluate."; return "Number of independent optimization runs to evaluate.";
} }
/**
*
*/
public String infoStringTipText() {
return "Infostring displayed on fitness graph by pressing the right mouse button.";
}
/** /**
* Use averaged graph for multi-run plots or not * Use averaged graph for multi-run plots or not
*/ */
@ -232,14 +225,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
return outputTo.getSelectedTagID() > 0; return outputTo.getSelectedTagID() > 0;
} }
public String convergenceRateThresholdTipText() {
return "Provided the optimal fitness is at zero, give the threshold below which it is considered as 'reached'";
}
/** /**
* @param x * @param x
*/ */
@Override @Override
@Parameter(description = "Provided the optimal fitness is at zero, give the threshold below which it is considered as 'reached'")
public void setConvergenceRateThreshold(double x) { public void setConvergenceRateThreshold(double x) {
convergenceRateThreshold = x; convergenceRateThreshold = x;
} }
@ -258,14 +248,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
} }
@Override @Override
@Parameter(description = "Output all available data fields or only the selected entries as value.")
public void setOutputAllFieldsAsText(boolean bShowFullText) { public void setOutputAllFieldsAsText(boolean bShowFullText) {
showAdditionalProblemInfo = bShowFullText; showAdditionalProblemInfo = bShowFullText;
} }
public String outputAllFieldsAsTextTipText() {
return "Output all available data fields or only the selected entries as value.";
}
public void hideHideable() { public void hideHideable() {
setOutputVerbosity(getOutputVerbosity()); setOutputVerbosity(getOutputVerbosity());
} }
@ -296,14 +283,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
} }
@Override @Override
@Parameter(description = "Set the interval of data output for intermediate verbosity (in generations).")
public void setOutputVerbosityK(int k) { public void setOutputVerbosityK(int k) {
verbosityK = k; verbosityK = k;
} }
public String outputVerbosityKTipText() {
return "Set the interval of data output for intermediate verbosity (in generations).";
}
@Override @Override
public SelectedTag getOutputTo() { public SelectedTag getOutputTo() {
return outputTo; return outputTo;
@ -314,13 +298,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
outputTo = tag; outputTo = tag;
} }
@Parameter(description = "Set the output destination; to deactivate output, set verbosity to none.")
public void setOutputTo(int i) { public void setOutputTo(int i) {
outputTo.setSelectedTag(i); outputTo.setSelectedTag(i);
} }
public String outputToTipText() {
return "Set the output destination; to deactivate output, set verbosity to none.";
}
@Override @Override
public StringSelection getFieldSelection() { public StringSelection getFieldSelection() {
@ -328,13 +310,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
} }
@Override @Override
@Parameter(description = "Select the data fields to be collected and plotted. Note that only simple types can be plotted to the GUI.")
public void setFieldSelection(StringSelection v) { public void setFieldSelection(StringSelection v) {
graphSel = v; graphSel = v;
} }
public String fieldSelectionTipText() {
return "Select the data fields to be collected and plotted. Note that only simple types can be plotted to the GUI.";
}
/** /**
* May be called to dynamically alter the set of graphs that can be * May be called to dynamically alter the set of graphs that can be

View File

@ -110,7 +110,6 @@ public class FileTools {
* a PrintWriter while other objects are written using an ObjectOutputStream. * a PrintWriter while other objects are written using an ObjectOutputStream.
* *
* @param parentComponent the parent component * @param parentComponent the parent component
* @param fc a filechooser or null to create a new one
* @param object The object to save. * @param object The object to save.
*/ */
public static boolean saveObjectWithFileChooser(Component parentComponent, Object object) { public static boolean saveObjectWithFileChooser(Component parentComponent, Object object) {
@ -208,10 +207,10 @@ public class FileTools {
String predefName = null; String predefName = null;
try { try {
predefName = (String) BeanInspector.callIfAvailable(object, "getName", null); predefName = (String) BeanInspector.callIfAvailable(object, "getName", null);
predefName = StringTools.simplifySymbols(predefName) + ".ser"; predefName = StringTools.simplifySymbols(predefName) + ".yml";
} catch (Exception e) { } catch (Exception e) {
predefName = object.getClass().getName(); predefName = object.getClass().getName();
predefName = StringTools.simplifySymbols(predefName) + ".ser"; predefName = StringTools.simplifySymbols(predefName) + ".yml";
} }
if (!folder.exists()) { if (!folder.exists()) {

View File

@ -0,0 +1,61 @@
package eva2.yaml;
import eva2.util.annotation.Hidden;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.introspector.Property;
import org.yaml.snakeyaml.representer.Representer;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Set;
import java.util.TreeSet;
/**
* Created by becker on 02.11.2014.
*/
public class BeanSerializer {
public static String serializeObject(Object obj) {
DumperOptions options = new DumperOptions();
options.setAllowReadOnlyProperties(false);
options.setIndent(4);
Yaml yaml = new Yaml(new OptimizationRepresenter(), options);
return yaml.dump(obj);
}
}
class OptimizationRepresenter extends Representer {
@Override
protected Set<Property> getProperties(Class<?> type)
throws IntrospectionException {
Set<Property> set = super.getProperties(type);
Set<Property> filtered = new TreeSet<>();
BeanInfo info = Introspector.getBeanInfo(type, Object.class);
PropertyDescriptor[] properties = info.getPropertyDescriptors();
ArrayList<String> hiddenProperties = new ArrayList<>();
// We don't want to save Hidden properties
for (PropertyDescriptor p : properties) {
Method setter = p.getWriteMethod();
if (setter != null && setter.isAnnotationPresent(Hidden.class) || p.isHidden()) {
hiddenProperties.add(p.getName());
}
}
for (Property prop : set) {
String name = prop.getName();
if (!hiddenProperties.contains(name)) {
filtered.add(prop);
}
}
return filtered;
}
}

View File

@ -1,4 +1,4 @@
package eva2.json; package eva2.yaml;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -0,0 +1,4 @@
/**
* YAML package for serializing and deserializing optimization configurations.
*/
package eva2.yaml;