Java tutorial
/* Copyright 2009-2012 David Hadka * 2013 Matthew Woodruff * * This file is based on part of the MOEA Framework. * * The MOEA Framework is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * The MOEA Framework is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the MOEA Framework. If not, see <http://www.gnu.org/licenses/>. */ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.Properties; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.moeaframework.core.Algorithm; import org.moeaframework.core.FrameworkException; import org.moeaframework.core.NondominatedPopulation; import org.moeaframework.core.PRNG; import org.moeaframework.core.PopulationIO; import org.moeaframework.core.Problem; import org.moeaframework.core.indicator.QualityIndicator; import org.moeaframework.core.spi.AlgorithmFactory; import org.moeaframework.core.spi.ProblemFactory; import org.moeaframework.problem.TimingProblem; import org.moeaframework.util.CommandLineUtility; import org.moeaframework.util.Localization; import org.moeaframework.util.TypedProperties; import org.moeaframework.analysis.sensitivity.*; /** * Command line utility for evaluating an algorithm using many * parameterizations. */ public class OneParameterization extends CommandLineUtility { /** * The problem being evaluated. */ protected Problem problem; /** * The output writer where end-of-run results are stored. */ protected OutputWriter output; /** * The sample reader from which input parameters are read. */ protected SampleReader input; /** * Constructs the command line utility for evaluating an algorithm using * many parameterizations. */ public OneParameterization() { super(); } @Override public void start(String[] args) { // trim last argument because of an error with Windows newline // characters if (args.length > 0) { args[args.length - 1] = args[args.length - 1].trim(); } Options options = getOptions(); CommandLineParser commandLineParser = new GnuParser(); CommandLine commandLine = null; try { commandLine = commandLineParser.parse(options, args); } catch (ParseException e) { System.err.println(e.getMessage()); } if ((commandLine == null) || commandLine.hasOption("help")) { // there's no helping you! System.exit(-1); } try { run(commandLine); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } @SuppressWarnings("static-access") @Override public Options getOptions() { Options options = super.getOptions(); options.addOption( OptionBuilder.withLongOpt("parameterFile").hasArg().withArgName("file").isRequired().create('p')); options.addOption(OptionBuilder.withLongOpt("input").hasArg().withArgName("file").isRequired().create('i')); options.addOption(OptionBuilder.withLongOpt("inputnumber").hasArg().withArgName("input number").isRequired() .create('u')); options.addOption( OptionBuilder.withLongOpt("output").hasArg().withArgName("file").isRequired().create('o')); options.addOption( OptionBuilder.withLongOpt("problem").hasArg().withArgName("name").isRequired().create('b')); options.addOption( OptionBuilder.withLongOpt("algorithm").hasArg().withArgName("name").isRequired().create('a')); options.addOption(OptionBuilder.withLongOpt("properties").hasArgs().withArgName("p1=v1;p2=v2;...") .withValueSeparator(';').create('x')); options.addOption(OptionBuilder.withLongOpt("seed").hasArg().withArgName("value").create('s')); options.addOption(OptionBuilder.withLongOpt("epsilon").hasArg().withArgName("e1,e2,...").create('e')); options.addOption(OptionBuilder.withLongOpt("metrics").create('m')); options.addOption(OptionBuilder.withLongOpt("reference").hasArg().withArgName("file").create('r')); options.addOption(OptionBuilder.withLongOpt("novariables").create('n')); options.addOption(OptionBuilder.withLongOpt("force").create('f')); //fill in option descriptions for (Object obj : options.getOptions()) { Option option = (Option) obj; option.setDescription(option.getLongOpt()); } return options; } @Override public String getDescription() { return Localization.getString(OneParameterization.class, "description"); } @Override public void run(CommandLine commandLine) throws IOException { File outputFile = new File(commandLine.getOptionValue("output")); File inputFile = new File(commandLine.getOptionValue("input")); ParameterFile parameterFile = new ParameterFile(new File(commandLine.getOptionValue("parameterFile"))); // sanity check to ensure input hasn't been modified after the output if (!commandLine.hasOption("force") && (outputFile.lastModified() > 0L) && (inputFile.lastModified() > outputFile.lastModified())) { throw new FrameworkException("input appears to be newer than output"); } // open the resources and begin processing try { problem = ProblemFactory.getInstance().getProblem(commandLine.getOptionValue("problem")); try { input = new SampleReader(new FileReader(inputFile), parameterFile); try { if (commandLine.hasOption("metrics")) { NondominatedPopulation referenceSet = null; // load reference set and create the quality indicator if (commandLine.hasOption("reference")) { referenceSet = new NondominatedPopulation( PopulationIO.readObjectives(new File(commandLine.getOptionValue("reference")))); } else { referenceSet = ProblemFactory.getInstance() .getReferenceSet(commandLine.getOptionValue("problem")); } if (referenceSet == null) { throw new FrameworkException("no reference set available"); } QualityIndicator indicator = new QualityIndicator(problem, referenceSet); output = new MetricFileWriter(indicator, outputFile); } else { output = new ResultFileWriter(problem, outputFile, !commandLine.hasOption("novariables")); } // resume at the last good output // for (int i = 0; i < output.getNumberOfEntries(); i++) { // if (input.hasNext()) { // input.next(); // } else { // throw new FrameworkException( // "output has more entries than input"); // } // } // only one input. scan forward to it Properties properties = new Properties(); if (commandLine.hasOption("inputnumber")) { long limit = Long.parseLong(commandLine.getOptionValue("inputnumber")); for (long ii = 0; ii <= limit; ii++) { if (input.hasNext()) { properties = input.next(); } else { throw new FrameworkException("input line does not exist"); } } } // setup any default parameters Properties defaultProperties = new Properties(); if (commandLine.hasOption("properties")) { for (String property : commandLine.getOptionValues("properties")) { String[] tokens = property.split("="); if (tokens.length == 2) { defaultProperties.setProperty(tokens[0], tokens[1]); } else { throw new FrameworkException("malformed property argument"); } } } if (commandLine.hasOption("epsilon")) { defaultProperties.setProperty("epsilon", commandLine.getOptionValue("epsilon")); } // seed the pseudo-random number generator if (commandLine.hasOption("seed")) { PRNG.setSeed(Long.parseLong(commandLine.getOptionValue("seed"))); } // process the remaining runs // while (input.hasNext()) { // Properties properties = input.next(); // properties.putAll(defaultProperties); // // process(commandLine.getOptionValue("algorithm"), // properties); // } properties.putAll(defaultProperties); process(commandLine.getOptionValue("algorithm"), properties); } finally { if (output != null) { output.close(); } } } finally { if (input != null) { input.close(); } } } finally { if (problem != null) { problem.close(); } } } /** * Performs a single run of the specified algorithm using the parameters. * * @param algorithmName the algorithm name * @param properties the parameters stored in a properties object * @throws IOException if an I/O error occurred */ protected void process(String algorithmName, Properties properties) throws IOException { // instrument the problem to record timing information TimingProblem timingProblem = new TimingProblem(problem); Algorithm algorithm = AlgorithmFactory.getInstance().getAlgorithm(algorithmName, properties, timingProblem); // find the maximum NFE to run if (!properties.containsKey("maxEvaluations")) { throw new FrameworkException("maxEvaluations not defined"); } int maxEvaluations = (int) Double.parseDouble(properties.getProperty("maxEvaluations")); // run the algorithm long startTime = System.nanoTime(); while (!algorithm.isTerminated() && (algorithm.getNumberOfEvaluations() < maxEvaluations)) { algorithm.step(); } long endTime = System.nanoTime(); // extract the result and free any resources NondominatedPopulation result = algorithm.getResult(); algorithm.terminate(); // apply epsilon-dominance if required if (properties.containsKey("epsilon")) { TypedProperties typedProperties = new TypedProperties(properties); double[] epsilon = typedProperties.getDoubleArray("epsilon", null); result = EpsilonHelper.convert(result, epsilon); } // record instrumented data Properties timingData = new Properties(); timingData.setProperty("EvaluationTime", Double.toString(timingProblem.getTime())); timingData.setProperty("TotalTime", Double.toString((endTime - startTime) / 1e9)); // write result to output output.append(new ResultEntry(result, timingData)); } /** * Starts the command line utility for evaluating an algorithm using many * parameterizations. * * @param args the command line arguments */ public static void main(String[] args) { new OneParameterization().start(args); } }