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

View File

@ -4,12 +4,11 @@ import eva2.optimization.go.InterfaceOptimizationParameters;
import eva2.optimization.operator.terminators.EvaluationTerminator;
import eva2.optimization.operator.terminators.InterfaceTerminator;
import eva2.optimization.strategies.DifferentialEvolution;
import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.problems.F1Problem;
import eva2.problems.InterfaceOptimizationProblem;
import eva2.optimization.strategies.GeneticAlgorithm;
import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.tools.Serializer;
import eva2.util.annotation.Description;
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@ -35,21 +34,21 @@ public class OptimizationParameters extends AbstractOptimizationParameters imple
* @return
*/
public static OptimizationParameters getInstance() {
return getInstance("OptimizationParameters.ser", true);
return getInstance("OptimizationParameters.yml", true);
}
/**
* 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
* @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;
try {
FileInputStream fileStream = new FileInputStream(serParamFile);
instance = (OptimizationParameters) Serializer.loadObject(fileStream, casually);
FileInputStream fileStream = new FileInputStream(yamlFile);
instance = (OptimizationParameters) new Yaml().load(fileStream);
} catch (FileNotFoundException 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.go.InterfaceNotifyOnInformers;
import eva2.optimization.go.InterfaceOptimizationParameters;
import eva2.optimization.population.InterfacePopulationChangedEventListener;
import eva2.optimization.operator.paramcontrol.ConstantParameters;
import eva2.optimization.operator.paramcontrol.InterfaceParameterControl;
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.GenerationTerminator;
import eva2.optimization.operator.terminators.InterfaceTerminator;
import eva2.optimization.population.InterfacePopulationChangedEventListener;
import eva2.optimization.population.Population;
import eva2.problems.AbstractOptimizationProblem;
import eva2.problems.InterfaceAdditionalPopulationInformer;
import eva2.optimization.statistics.InterfaceStatistics;
import eva2.optimization.statistics.InterfaceTextListener;
import eva2.optimization.statistics.StatisticsWithGUI;
import eva2.optimization.strategies.InterfaceOptimizer;
import eva2.problems.AbstractOptimizationProblem;
import eva2.problems.InterfaceAdditionalPopulationInformer;
import eva2.problems.InterfaceOptimizationProblem;
import eva2.tools.EVAERROR;
import eva2.tools.StringTools;
@ -48,7 +48,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
private InterfaceStatistics statistics;
private InterfaceOptimizationParameters optimizationParameters;
private boolean createInitialPopulations = true;
private boolean saveParams = false;
private boolean saveParams = true;
private OptimizationStateListener optimizationStateListener;
private boolean wasRestarted = false;
private int runCounter = 0;
@ -167,7 +167,6 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
EVAERROR.clearMsgCache();
while (isOptimizationRunning()) {
setPriority(3);
// ToDo: Do we need this really?
if (saveParams) {
try {
optimizationParameters.saveInstance();

View File

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

View File

@ -9,6 +9,7 @@ import eva2.tools.SelectedTag;
import eva2.tools.Serializer;
import eva2.tools.StringSelection;
import eva2.util.annotation.Description;
import eva2.util.annotation.Parameter;
import java.io.FileInputStream;
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.")
public class StatisticsParameters implements InterfaceStatisticsParameters, InterfaceNotifyOnInformers, Serializable {
private static final long serialVersionUID = -8681061379203108390L;
private static final Logger LOGGER = Logger.getLogger(StatisticsParameters.class.getName());
public final static int VERBOSITY_NONE = 0;
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.";
}
/**
*
*/
public String infoStringTipText() {
return "Infostring displayed on fitness graph by pressing the right mouse button.";
}
/**
* Use averaged graph for multi-run plots or not
*/
@ -232,14 +225,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
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
*/
@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) {
convergenceRateThreshold = x;
}
@ -258,14 +248,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
}
@Override
@Parameter(description = "Output all available data fields or only the selected entries as value.")
public void setOutputAllFieldsAsText(boolean bShowFullText) {
showAdditionalProblemInfo = bShowFullText;
}
public String outputAllFieldsAsTextTipText() {
return "Output all available data fields or only the selected entries as value.";
}
public void hideHideable() {
setOutputVerbosity(getOutputVerbosity());
}
@ -296,14 +283,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
}
@Override
@Parameter(description = "Set the interval of data output for intermediate verbosity (in generations).")
public void setOutputVerbosityK(int k) {
verbosityK = k;
}
public String outputVerbosityKTipText() {
return "Set the interval of data output for intermediate verbosity (in generations).";
}
@Override
public SelectedTag getOutputTo() {
return outputTo;
@ -314,13 +298,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
outputTo = tag;
}
@Parameter(description = "Set the output destination; to deactivate output, set verbosity to none.")
public void setOutputTo(int i) {
outputTo.setSelectedTag(i);
}
public String outputToTipText() {
return "Set the output destination; to deactivate output, set verbosity to none.";
}
@Override
public StringSelection getFieldSelection() {
@ -328,13 +310,11 @@ public class StatisticsParameters implements InterfaceStatisticsParameters, Inte
}
@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) {
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

View File

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

View File

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