/* 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 org.moeaframework.algorithm.pisa;
import java.io.IOException;
import java.util.Properties;
import org.moeaframework.core.Algorithm;
import org.moeaframework.core.FrameworkException;
import org.moeaframework.core.Problem;
import org.moeaframework.core.Settings;
import org.moeaframework.core.Variation;
import org.moeaframework.core.spi.AlgorithmProvider;
import org.moeaframework.core.spi.OperatorFactory;
import org.moeaframework.core.spi.ProviderNotFoundException;
/**
* Algorithm provider for PISA selectors. In order to make a PISA selector
* available for this provider, two steps are required. First, the PISA selector
* must be downloaded and, if necessary, compiled. Second, the configuration
* file (typically {@code global.properties}) must be updated with the new
* PISA selector. As an example, for the HypE selector, add the selector name,
* {@code hype}, to the list of PISA algorithms:
* <pre>
* org.moeaframework.util.pisa.algorithms = hype, spea2, nsga2
* </pre>
* For each algorithm, define its configuration options below. For the example
* of {@code hype}, specify the following:
* <ol>
* <li>The executable to run:
* <pre>
* org.moeaframework.algorithm.pisa.hype.command = ./path/to/hype.exe
* </pre>
* <li>The list of parameters:
* <pre>
* org.moeaframework.algorithm.pisa.hype.parameters = seed, tournament, mating, bound, nrOfSamples
* </pre>
* The order typically matters, so ensure the parameters are listed in the
* same order as expected by the executable.
* <li>For each parameter, specify its default value:
* <pre>
* org.moeaframework.algorithm.pisa.hype.parameter.tournament = 5
* org.moeaframework.algorithm.pisa.hype.parameter.mating = 1
* ...
* </pre>
* It is not necessary to give a default for the seed parameter as it is
* set automatically by the MOEA Framework.
* </ol>
* Note: Prior to version 1.14, the MOEA Framework only accepted a static
* version of the algorithm parameters using the option:
* <pre>
* org.moeaframework.algorithm.pisa.hype.configuration = ./path/to/hype_params.txt
* </pre>
* This is still accepted, but would mean the MOEA Framework is unable to
* change the algorithm parameters. Once completed, the PISA selector can be
* used with:
* <pre>
* Algorithm algorithm = AlgorithmFactory.getInstance().getAlgorithm("hype", properties, problem);
* </pre>
*/
public class PISAAlgorithms extends AlgorithmProvider {
/**
* Constructs an algorithm provider for PISA selectors.
*/
public PISAAlgorithms() {
super();
}
/**
* Returns the case-sensitive version of the PISA algorithm name.
*
* @param name the case-insensitive name
* @return the case-sensitive name
*/
protected String getCaseSensitiveSelectorName(String name) {
for (String selector : Settings.getPISAAlgorithms()) {
if (selector.equalsIgnoreCase(name)) {
return selector;
}
}
return null;
}
@Override
public Algorithm getAlgorithm(String name, Properties properties,
Problem problem) {
//lookup the case-sensitive version of the PISA algorithm name to
//generate the correct property keys
name = getCaseSensitiveSelectorName(name);
if (name != null) {
if (problem.getNumberOfConstraints() > 0) {
throw new ProviderNotFoundException(name,
new FrameworkException("constraints not supported"));
}
try {
Variation variation = OperatorFactory.getInstance()
.getVariation(null, properties, problem);
return new PISAAlgorithm(name, problem, variation, properties);
} catch (IOException e) {
throw new ProviderNotFoundException(name, e);
}
} else {
return null;
}
}
}