iDynoOptimizer.MOEAFramework26.src.org.moeaframework.analysis.sensitivity.ExtractData.java Source code

Java tutorial

Introduction

Here is the source code for iDynoOptimizer.MOEAFramework26.src.org.moeaframework.analysis.sensitivity.ExtractData.java

Source

/* Copyright 2009-2015 David Hadka
 *
 * This file is 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/>.
 */
package iDynoOptimizer.MOEAFramework26.src.org.moeaframework.analysis.sensitivity;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.FrameworkException;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.Indicator;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.NondominatedPopulation;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.PopulationIO;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.Problem;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.AdditiveEpsilonIndicator;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.Contribution;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.GenerationalDistance;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.Hypervolume;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.InvertedGenerationalDistance;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.MaximumParetoFrontError;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.R1Indicator;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.R2Indicator;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.R3Indicator;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.indicator.Spacing;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.core.spi.ProblemFactory;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.CommandLineUtility;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.OptionCompleter;
import iDynoOptimizer.MOEAFramework26.src.org.moeaframework.util.TypedProperties;

/**
 * Command line utility for extracting data from a result file.  The data that
 * can be extracted includes any properties by providing its full name, or any
 * of the following metrics if given the designated {@code +option}.
 * <ul>
 *   <li>{@code +hypervolume} for {@link Hypervolume}
 *   <li>{@code +generational} for {@link GenerationalDistance}
 *   <li>{@code +inverted} for {@link InvertedGenerationalDistance}
 *   <li>{@code +epsilon} for {@link AdditiveEpsilonIndicator}
 *   <li>{@code +error} for {@link MaximumParetoFrontError}
 *   <li>{@code +spacing} for {@link Spacing}
 *   <li>{@code +contribution} for {@link Contribution}
 *   <li>{@code +R1} for {@link R1Indicator}
 *   <li>{@code +R2} for {@link R2Indicator}
 *   <li>{@code +R3} for {@link R3Indicator}
 * </ul>
 */
public class ExtractData extends CommandLineUtility {

    /**
     * The problem.
     */
    private Problem problem;

    /**
     * The reference set; {@code null} if the reference set has not yet been
     * loaded.
     */
    private NondominatedPopulation referenceSet;

    /**
     * Constructs the command line utility for extracting data from a result
     * file.
     */
    public ExtractData() {
        super();
    }

    @SuppressWarnings("static-access")
    @Override
    public Options getOptions() {
        Options options = super.getOptions();

        OptionGroup group = new OptionGroup();
        group.setRequired(true);
        group.addOption(OptionBuilder.withLongOpt("problem").hasArg().withArgName("name").create('b'));
        group.addOption(OptionBuilder.withLongOpt("dimension").hasArg().withArgName("number").create('d'));
        options.addOptionGroup(group);

        options.addOption(OptionBuilder.withLongOpt("input").hasArg().withArgName("file").isRequired().create('i'));
        options.addOption(OptionBuilder.withLongOpt("output").hasArg().withArgName("file").create('o'));
        options.addOption(OptionBuilder.withLongOpt("separator").hasArg().withArgName("value").create('s'));
        options.addOption(OptionBuilder.withLongOpt("reference").hasArg().withArgName("file").create('r'));
        options.addOption(OptionBuilder.withLongOpt("epsilon").hasArg().withArgName("e1,e2,...").create('e'));
        options.addOption(OptionBuilder.withLongOpt("noheader").create('n'));

        return options;
    }

    @Override
    public void run(CommandLine commandLine) throws Exception {
        String separator = commandLine.hasOption("separator") ? commandLine.getOptionValue("separator") : " ";

        String[] fields = commandLine.getArgs();

        // indicators are prepared, run the data extraction routine
        ResultFileReader input = null;
        PrintStream output = null;

        try {
            // setup the problem
            if (commandLine.hasOption("problem")) {
                problem = ProblemFactory.getInstance().getProblem(commandLine.getOptionValue("problem"));
            } else {
                problem = new ProblemStub(Integer.parseInt(commandLine.getOptionValue("dimension")));
            }

            try {
                input = new ResultFileReader(problem, new File(commandLine.getOptionValue("input")));

                try {
                    output = commandLine.hasOption("output")
                            ? new PrintStream(new File(commandLine.getOptionValue("output")))
                            : System.out;

                    // optionally print header line
                    if (!commandLine.hasOption("noheader")) {
                        output.print('#');

                        for (int i = 0; i < fields.length; i++) {
                            if (i > 0) {
                                output.print(separator);
                            }

                            output.print(fields[i]);
                        }

                        output.println();
                    }

                    // process entries
                    while (input.hasNext()) {
                        ResultEntry entry = input.next();
                        Properties properties = entry.getProperties();

                        for (int i = 0; i < fields.length; i++) {
                            if (i > 0) {
                                output.print(separator);
                            }

                            if (properties.containsKey(fields[i])) {
                                output.print(properties.getProperty(fields[i]));
                            } else if (fields[i].startsWith("+")) {
                                output.print(evaluate(fields[i].substring(1), entry, commandLine));
                            } else {
                                throw new FrameworkException("missing field");
                            }
                        }

                        output.println();
                    }
                } finally {
                    if ((output != null) && (output != System.out)) {
                        output.close();
                    }
                }
            } finally {
                if (input != null) {
                    input.close();
                }
            }
        } finally {
            if (problem != null) {
                problem.close();
            }
        }
    }

    /**
     * Evaluates the special commands.  The {@code +} prefix should be removed
     * prior to calling this method.  An {@link OptionCompleter} is used to
     * auto-complete the commands, so only the unique prefix must be provided.
     * 
     * @param command the command identifier
     * @param entry the entry in the result file
     * @param commandLine the command line options
     * @return the value of the special command
     * @throws FrameworkException if the command is not supported
     * @throws IOException if an I/O error occurred
     */
    protected String evaluate(String command, ResultEntry entry, CommandLine commandLine) throws IOException {
        OptionCompleter completer = new OptionCompleter("hypervolume", "generational", "inverted", "epsilon",
                "error", "spacing", "contribution", "R1", "R2", "R3");
        String option = completer.lookup(command);

        if (option == null) {
            throw new FrameworkException("unsupported command");
        }

        //load the reference set
        if (referenceSet == null) {
            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");
            }
        }

        //create the indicator, these should perhaps be cached for speed
        Indicator indicator = null;

        if (option.equals("hypervolume")) {
            indicator = new Hypervolume(problem, referenceSet);
        } else if (option.equals("generational")) {
            indicator = new GenerationalDistance(problem, referenceSet);
        } else if (option.equals("inverted")) {
            indicator = new InvertedGenerationalDistance(problem, referenceSet);
        } else if (option.equals("epsilon")) {
            indicator = new AdditiveEpsilonIndicator(problem, referenceSet);
        } else if (option.equals("error")) {
            indicator = new MaximumParetoFrontError(problem, referenceSet);
        } else if (option.equals("spacing")) {
            indicator = new Spacing(problem);
        } else if (option.equals("contribution")) {
            if (commandLine.hasOption("epsilon")) {
                double[] epsilon = TypedProperties.withProperty("epsilon", commandLine.getOptionValue("epsilon"))
                        .getDoubleArray("epsilon", null);
                indicator = new Contribution(referenceSet, epsilon);
            } else {
                indicator = new Contribution(referenceSet);
            }
        } else if (option.equals("R1")) {
            indicator = new R1Indicator(problem, R1Indicator.getDefaultSubdivisions(problem), referenceSet);
        } else if (option.equals("R2")) {
            indicator = new R2Indicator(problem, R2Indicator.getDefaultSubdivisions(problem), referenceSet);
        } else if (option.equals("R3")) {
            indicator = new R3Indicator(problem, R3Indicator.getDefaultSubdivisions(problem), referenceSet);
        } else {
            throw new IllegalStateException();
        }

        return Double.toString(indicator.evaluate(entry.getPopulation()));
    }

    /**
     * Starts the command line utility for extracting data from a result file.
     * 
     * @param args the command line arguments
     * @throws Exception if an error occurred
     */
    public static void main(String[] args) throws Exception {
        new ExtractData().start(args);
    }

}