Lots of documenation

Refactoring
Read CLI params
This commit is contained in:
Fabian Becker 2013-12-09 00:25:25 +01:00
parent 46e4e4e80f
commit fc2ea13611

View File

@ -8,30 +8,64 @@ import eva2.optimization.operator.terminators.CombinedTerminator;
import eva2.optimization.operator.terminators.EvaluationTerminator; import eva2.optimization.operator.terminators.EvaluationTerminator;
import eva2.optimization.operator.terminators.FitnessValueTerminator; import eva2.optimization.operator.terminators.FitnessValueTerminator;
import eva2.optimization.problems.AbstractOptimizationProblem; import eva2.optimization.problems.AbstractOptimizationProblem;
import eva2.optimization.problems.F1Problem;
import eva2.optimization.problems.InterfaceOptimizationProblem;
import eva2.optimization.strategies.InterfaceOptimizer; import eva2.optimization.strategies.InterfaceOptimizer;
import org.apache.commons.cli.*; import org.apache.commons.cli.*;
import org.reflections.Reflections; import org.reflections.Reflections;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Main Class for the EvA2 Command Line Interface
*
* The command line interface features a limited subset of the EvA2
* optimization suite since it's difficult to parameterize all available
* classes in EvA2 from the command line.
* Supported Features:
* - Select all optimization problems that implement InterfaceOptimizationProblem
* - Select all optimizers that implement InterfaceOptimizer
* * Not all optimizers are configurable on the command line and will run
* with default parameters.
* * Optimizers can use the @Description / @Parameter annotations to specify
* parameters for CLI
* - Configure default parameters
* * Population size
* * Number of optimization runs (multi-runs)
* - Termination:
* * Not configurable!
* * Default: EvaluationTerminator(20000)
*/
public class Main implements OptimizationStateListener, InterfacePopulationChangedEventListener { public class Main implements OptimizationStateListener, InterfacePopulationChangedEventListener {
private static Logger LOGGER = Logger.getLogger(Main.class.getName());
private int populationSize = 20;
private int numberOfRuns = 1;
private long seed = System.currentTimeMillis();
private AbstractOptimizationProblem problem;
private InterfaceOptimizer optimizer;
/**
private static Options createDefaultCommandLineOptions() { * Creates a set of default options used in all optimizations.
*
* @return Options Default options used for optimizations
*/
private Options createDefaultCommandLineOptions() {
Options opt = new Options(); Options opt = new Options();
opt.addOption(OptionBuilder opt.addOption(OptionBuilder
.withLongOpt("optimizer") .withLongOpt("optimizer")
.withDescription("Optimizer") .withDescription("Optimizer")
.hasArg()
.create("op") .create("op")
); );
opt.addOption("ps", "popsize", true, "Population size"); opt.addOption("ps", "popsize", true, "Population size");
opt.addOption("n", "runs", true, "Number of runs to perform");
opt.addOption("s", "seed", true, "Random seed");
opt.addOption(OptionBuilder opt.addOption(OptionBuilder
.withLongOpt("help") .withLongOpt("help")
.withDescription("Shows this help message or specific help for [optimizer]") .withDescription("Shows this help message or specific help for [optimizer]")
@ -39,6 +73,12 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
.create('h') .create('h')
); );
opt.addOption(OptionBuilder
.withLongOpt("problem")
.withDescription("Select Optimization Problem to optimize.")
.hasArg()
.create('p')
);
return opt; return opt;
} }
@ -85,7 +125,7 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
Reflections reflections = new Reflections("eva2.optimization.strategies"); Reflections reflections = new Reflections("eva2.optimization.strategies");
Set<Class<? extends InterfaceOptimizer>> optimizers = reflections.getSubTypesOf(InterfaceOptimizer.class); Set<Class<? extends InterfaceOptimizer>> optimizers = reflections.getSubTypesOf(InterfaceOptimizer.class);
for (Class<? extends InterfaceOptimizer> optimizer : optimizers) { for (Class<? extends InterfaceOptimizer> optimizer : optimizers) {
// We only want instantiable classes.ya // We only want instantiable classes
if (optimizer.isInterface() || Modifier.isAbstract(optimizer.getModifiers())) { if (optimizer.isInterface() || Modifier.isAbstract(optimizer.getModifiers())) {
continue; continue;
} }
@ -94,11 +134,11 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
return optimizerList; return optimizerList;
} }
public static Map<String, Class<? extends InterfaceOptimizationProblem>> createProblemList() { public static Map<String, Class<? extends AbstractOptimizationProblem>> createProblemList() {
Map<String, Class<? extends InterfaceOptimizationProblem>> problemList = new TreeMap<String, Class<? extends InterfaceOptimizationProblem>>(); Map<String, Class<? extends AbstractOptimizationProblem>> problemList = new TreeMap<String, Class<? extends AbstractOptimizationProblem>>();
Reflections reflections = new Reflections("eva2.optimization.problems"); Reflections reflections = new Reflections("eva2.optimization.problems");
Set<Class<? extends InterfaceOptimizationProblem>> problems = reflections.getSubTypesOf(InterfaceOptimizationProblem.class); Set<Class<? extends AbstractOptimizationProblem>> problems = reflections.getSubTypesOf(AbstractOptimizationProblem.class);
for (Class<? extends InterfaceOptimizationProblem> problem : problems) { for (Class<? extends AbstractOptimizationProblem> problem : problems) {
// We only want instantiable classes // We only want instantiable classes
if (problem.isInterface() || Modifier.isAbstract(problem.getModifiers())) { if (problem.isInterface() || Modifier.isAbstract(problem.getModifiers())) {
continue; continue;
@ -114,12 +154,28 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
} }
public static void main(String[] args) { public static void main(String[] args) {
Main optimizationMain = new Main(args);
optimizationMain.runOptimization();
}
public Main(String[] args) {
int index = Arrays.asList(args).indexOf("--");
String[] programParams = args;
String[] optimizerParams;
if (index >= 0) {
programParams = Arrays.copyOfRange(args, 0, index);
optimizerParams = Arrays.copyOfRange(args, index + 1, args.length - 1);
} else {
optimizerParams = new String[]{};
}
/** /**
* Default command line options only require help or optimizer. * Default command line options only require help or optimizer.
* Later we build extended command line options depending on * Later we build extended command line options depending on
* the selected optimizer. * the selected optimizer.
*/ */
Options defaultOptions = createDefaultCommandLineOptions(); Options defaultOptions = this.createDefaultCommandLineOptions();
/** /**
* Parse default options. * Parse default options.
@ -127,7 +183,7 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
CommandLineParser cliParser = new BasicParser(); CommandLineParser cliParser = new BasicParser();
CommandLine commandLine = null; CommandLine commandLine = null;
try { try {
commandLine = cliParser.parse(defaultOptions, args); commandLine = cliParser.parse(defaultOptions, programParams);
} catch (ParseException e) { } catch (ParseException e) {
showHelp(defaultOptions); showHelp(defaultOptions);
System.exit(-1); System.exit(-1);
@ -141,14 +197,50 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
if ("optimizer".equals(helpOption)) { if ("optimizer".equals(helpOption)) {
showOptimizerHelp(); showOptimizerHelp();
} else if ("problem".equals(helpOption)) { } else if ("problem".equals(helpOption)) {
showProblemHelp(); listProblems();
} else { } else {
showHelp(defaultOptions); showHelp(defaultOptions);
} }
System.exit(0);
} }
Main optimizationMain = new Main(); // OK, so we've got valid parameters - let's setup the optimizer and problem
optimizationMain.runOptimization(); if (commandLine.hasOption("popsize")) {
this.populationSize = Integer.parseInt(commandLine.getOptionValue("popsize"));
}
if (commandLine.hasOption("runs")) {
this.numberOfRuns = Integer.parseInt(commandLine.getOptionValue("runs"));
}
if (commandLine.hasOption("seed")) {
this.seed = Long.parseLong(commandLine.getOptionValue("seed"));
}
if (commandLine.hasOption("problem")) {
String problemName = commandLine.getOptionValue("problem");
setProblemFromName(problemName);
}
if (commandLine.hasOption("optimizer")) {
String optimizerName = commandLine.getOptionValue("optimizer");
}
}
private void setProblemFromName(String problemName) {
Map<String, Class<? extends AbstractOptimizationProblem>> problemList = createProblemList();
Class<? extends AbstractOptimizationProblem> problem = problemList.get(problemName);
try {
this.problem = problem.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} }
private void runOptimization() { private void runOptimization() {
@ -157,15 +249,13 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
OptimizerFactory.setEvaluationTerminator(50000); OptimizerFactory.setEvaluationTerminator(50000);
OptimizerFactory.addTerminator(new FitnessValueTerminator(new double[]{0.01}), CombinedTerminator.OR); OptimizerFactory.addTerminator(new FitnessValueTerminator(new double[]{0.01}), CombinedTerminator.OR);
LOGGER.log(Level.INFO, "Running {0}", "Differential Evolution");
int popsize = 30;
double f = 0.8, lambda = 0.6, cr = 0.6; double f = 0.8, lambda = 0.6, cr = 0.6;
AbstractOptimizationProblem problem = new F1Problem(popsize); InterfaceOptimizer optimizer = OptimizerFactory.createDifferentialEvolution(this.problem, this.populationSize, f, lambda, cr, this);
InterfaceOptimizer optimizer = OptimizerFactory.createDifferentialEvolution(problem, popsize, f, lambda, cr, this); OptimizationParameters params = OptimizerFactory.makeParams(optimizer, this.populationSize, this.problem);
OptimizationParameters params = OptimizerFactory.makeParams(optimizer, popsize, problem);
double[] result = OptimizerFactory.optimizeToDouble(params); double[] result = OptimizerFactory.optimizeToDouble(params);
// This is stupid - why isn't there a way to wait for the optimization to finish? // This is stupid - why isn't there a way to wait for the optimization to finish?
@ -182,16 +272,16 @@ public class Main implements OptimizationStateListener, InterfacePopulationChang
System.out.println("Available Optimizers:"); System.out.println("Available Optimizers:");
for (String name : optimizerList.keySet()) { for (String name : optimizerList.keySet()) {
System.out.printf("\t%s\n", name); System.out.printf("%s\n", name);
} }
} }
private static void showProblemHelp() { private static void listProblems() {
Map<String, Class<? extends InterfaceOptimizationProblem>> problemList = createProblemList(); Map<String, Class<? extends AbstractOptimizationProblem>> problemList = createProblemList();
System.out.println("Available Problems:"); System.out.println("Available Problems:");
for (String name : problemList.keySet()) { for (String name : problemList.keySet()) {
System.out.printf("\t%s\n", name); System.out.printf("%s\n", name);
} }
} }