/* Copyright 2009-2016 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.jmetal;
import java.util.HashMap;
import java.util.Properties;
import jmetal.core.Operator;
import jmetal.core.SolutionType;
import jmetal.encodings.solutionType.BinaryRealSolutionType;
import jmetal.encodings.solutionType.BinarySolutionType;
import jmetal.encodings.solutionType.PermutationSolutionType;
import jmetal.encodings.solutionType.RealSolutionType;
import jmetal.metaheuristics.abyss.AbYSS;
import jmetal.metaheuristics.cellde.CellDE;
import jmetal.metaheuristics.densea.DENSEA;
import jmetal.metaheuristics.fastPGA.FastPGA;
import jmetal.metaheuristics.gde3.GDE3;
import jmetal.metaheuristics.ibea.IBEA;
import jmetal.metaheuristics.mocell.MOCell;
import jmetal.metaheuristics.mochc.MOCHC;
import jmetal.metaheuristics.nsgaII.NSGAII;
import jmetal.metaheuristics.omopso.OMOPSO;
import jmetal.metaheuristics.paes.PAES;
import jmetal.metaheuristics.pesa2.PESA2;
import jmetal.metaheuristics.smpso.SMPSO;
import jmetal.metaheuristics.smsemoa.SMSEMOA;
import jmetal.metaheuristics.spea2.SPEA2;
import jmetal.operators.crossover.DifferentialEvolutionCrossover;
import jmetal.operators.crossover.HUXCrossover;
import jmetal.operators.crossover.PMXCrossover;
import jmetal.operators.crossover.SBXCrossover;
import jmetal.operators.crossover.SinglePointCrossover;
import jmetal.operators.localSearch.MutationLocalSearch;
import jmetal.operators.mutation.BitFlipMutation;
import jmetal.operators.mutation.NonUniformMutation;
import jmetal.operators.mutation.PolynomialMutation;
import jmetal.operators.mutation.SwapMutation;
import jmetal.operators.mutation.UniformMutation;
import jmetal.operators.selection.BinaryTournament;
import jmetal.operators.selection.BinaryTournament2;
import jmetal.operators.selection.DifferentialEvolutionSelection;
import jmetal.operators.selection.RandomSelection;
import jmetal.operators.selection.RankingAndCrowdingSelection;
import jmetal.util.JMException;
import jmetal.util.comparators.FPGAFitnessComparator;
import jmetal.util.comparators.FitnessComparator;
import org.moeaframework.analysis.sensitivity.EpsilonHelper;
import org.moeaframework.core.Algorithm;
import org.moeaframework.core.Problem;
import org.moeaframework.core.spi.AlgorithmProvider;
import org.moeaframework.core.spi.ProviderNotFoundException;
import org.moeaframework.util.TypedProperties;
/**
* Algorithm provider for JMetal algorithms. Supports the following algorithms:
* <p>
* <table width="100%" border="1" cellpadding="3" cellspacing="0">
* <tr class="TableHeadingColor">
* <th width="10%" align="left">Name</th>
* <th width="10%" align="left">Type</th>
* <th width="80%" align="left">Properties</th>
* </tr>
* <tr>
* <td>AbYSS</td>
* <td>Real</td>
* <td>{@code populationSize, refSet1Size, refSet2Size, archiveSize,
* maxEvaluations, improvementRounds}</td>
* </tr>
* <tr>
* <td>CellDE</td>
* <td>Real*</td>
* <td>{@code populationSize, archiveSize, maxEvaluations, feedBack,
* de.crossoverRate, de.stepSize}</td>
* </tr>
* <tr>
* <td>DENSEA</td>
* <td>Any</td>
* <td>{@code populationSize, maxEvaluations}</td>
* </tr>
* <tr>
* <td>FastPGA</td>
* <td>Any</td>
* <td>{@code maxPopSize, initialPopulationSize, maxEvaluations, a, b, c, d,
* termination}</td>
* </tr>
* <tr>
* <td>GDE3</td>
* <td>Real*</td>
* <td>{@code populationSize, maxEvaluations, de.crossoverRate,
* de.stepSize}</td>
* </tr>
* <tr>
* <td>IBEA</td>
* <td>Any</td>
* <td>{@code populationSize, archiveSize, maxEvaluations}</td>
* </tr>
* <tr>
* <td>MOCell</td>
* <td>Any</td>
* <td>{@code populationSize, archiveSize, maxEvaluations, feedBack}</td>
* </tr>
* <tr>
* <td>MOCHC</td>
* <td>Binary*</td>
* <td>{@code initialConvergenceCount, preservedPopulation,
* convergenceValue, populationSize, maxEvaluations, hux.rate,
* bf.rate}</td>
* </tr>
* <tr>
* <td>NSGAII</td>
* <td>Any</td>
* <td>{@code populationSize, maxEvaluations}</td>
* </tr>
* <tr>
* <td>OMOPSO</td>
* <td>Real*</td>
* <td>{@code populationSize, archiveSize, maxEvaluations,
* mutationProbability, perturbationIndex, epsilon}</td>
* </tr>
* <tr>
* <td>PAES</td>
* <td>Any</td>
* <td>{@code archiveSize, bisections, maxEvaluations}</td>
* </tr>
* <tr>
* <td>PESA2</td>
* <td>Any</td>
* <td>{@code populationSize, archiveSize, bisections, maxEvaluations}</td>
* </tr>
* <tr>
* <td>SMPSO</td>
* <td>Real*</td>
* <td>{@code populationSize, archiveSize, maxEvaluations, pm.rate,
* pm.distributionIndex}</td>
* </tr>
* <tr>
* <td>SMSEMOA</td>
* <td>Any</td>
* <td>{@code populationSize, maxEvaluations, offset}</td>
* </tr>
* <tr>
* <td>SPEA2</td>
* <td>Any</td>
* <td>{@code populationSize, archiveSize, maxEvaluations}</td>
* </tr>
* </table>
* <p>
* You may also append {@code "-JMetal"} to any algorithm name to use the
* JMetal implementation incase it is overridden by another implementation.
* For example, use {@code "NSGAII-JMetal"}.
* <p>
* Unless the type is marked with *, the algorithm uses one of the types listed
* below. Note that only the types below are supported. Algorithms marked
* with * define operators specific to that algorithm. See the JMetal
* documentation for additional details.
* <p>
* <table width="100%" border="1" cellpadding="3" cellspacing="0">
* <tr class="TableHeadingColor">
* <th width="10%" align="left">Type</th>
* <th width="20%" align="left">Operators</th>
* <th width="70%" align="left">Parameters</th>
* </tr>
* <tr>
* <td>Real</td>
* <td>SBX, PM</td>
* <td>{@code sbx.rate, sbx.distributionIndex, pm.rate,
* pm.distributionIndex}</td>
* </tr>
* <tr>
* <td>Binary</td>
* <td>Single-Point, Bit Flip</td>
* <td>{@code 1x.rate, bf.rate}</td>
* </tr>
* <tr>
* <td>Permutation</td>
* <td>PMX, Swap</td>
* <td>{@code pmx.rate, swap.rate}</td>
* </tr>
* </table>
*/
public class JMetalAlgorithms extends AlgorithmProvider {
/**
* Constructs a JMetal algorithm provider.
*/
public JMetalAlgorithms() {
super();
}
@Override
public Algorithm getAlgorithm(String name, Properties properties,
Problem problem) {
TypedProperties typedProperties = new TypedProperties(properties);
JMetalProblemAdapter adapter = new JMetalProblemAdapter(problem);
jmetal.core.Algorithm algorithm = null;
try {
if (name.equalsIgnoreCase("AbYSS") ||
name.equalsIgnoreCase("AbYSS-JMetal")) {
algorithm = newAbYSS(typedProperties, adapter);
} else if (name.equalsIgnoreCase("CellDE") ||
name.equalsIgnoreCase("CellDE-JMetal")) {
algorithm = newCellDE(typedProperties, adapter);
} else if (name.equalsIgnoreCase("DENSEA") ||
name.equalsIgnoreCase("DENSEA-JMetal")) {
algorithm = newDENSEA(typedProperties, adapter);
} else if (name.equalsIgnoreCase("FastPGA") ||
name.equalsIgnoreCase("FastPGA-JMetal")) {
algorithm = newFastPGA(typedProperties, adapter);
} else if (name.equalsIgnoreCase("GDE3") ||
name.equalsIgnoreCase("GDE3-JMetal")) {
algorithm = newGDE3(typedProperties, adapter);
} else if (name.equalsIgnoreCase("IBEA") ||
name.equalsIgnoreCase("IBEA-JMetal")) {
algorithm = newIBEA(typedProperties, adapter);
} else if (name.equalsIgnoreCase("MOCell") ||
name.equalsIgnoreCase("MOCell-JMetal")) {
algorithm = newMOCell(typedProperties, adapter);
} else if (name.equalsIgnoreCase("MOCHC") ||
name.equalsIgnoreCase("MOCHC-JMetal")) {
algorithm = newMOCHC(typedProperties, adapter);
} else if (name.equalsIgnoreCase("NSGAII") ||
name.equalsIgnoreCase("NSGAII-JMetal")) {
algorithm = newNSGAII(typedProperties, adapter);
} else if (name.equalsIgnoreCase("OMOPSO") ||
name.equalsIgnoreCase("OMOPSO-JMetal")) {
algorithm = newOMOPSO(typedProperties, adapter);
} else if (name.equalsIgnoreCase("PAES") ||
name.equalsIgnoreCase("PAES-JMetal")) {
algorithm = newPAES(typedProperties, adapter);
} else if (name.equalsIgnoreCase("PESA2") ||
name.equalsIgnoreCase("PESA2-JMetal")) {
algorithm = newPESA2(typedProperties, adapter);
} else if (name.equalsIgnoreCase("SMPSO") ||
name.equalsIgnoreCase("SMPSO-JMetal")) {
algorithm = newSMPSO(typedProperties, adapter);
} else if (name.equalsIgnoreCase("SMSEMOA") ||
name.equalsIgnoreCase("SMSEMOA-JMetal")) {
algorithm = newSMSEMOA(typedProperties, adapter);
} else if (name.equalsIgnoreCase("SPEA2") ||
name.equalsIgnoreCase("SPEA2-JMetal")) {
algorithm = newSPEA2(typedProperties, adapter);
}
} catch (JMException e) {
throw new ProviderNotFoundException(name, e);
}
if (algorithm == null) {
return null;
} else {
return new JMetalAlgorithmAdapter(algorithm, adapter);
}
}
/**
* Adds the appropriate variation operators to the algorithm for the
* specified problem. Currently supports {@code Binary}, {@code BinaryReal},
* {@code Real} and {@code Permutation} encodings.
*
* @param algorithm the algorithm which will use the operators
* @param properties the properties for customizing the operators
* @param problem the problem adapter
* @throws JMException if an error occurred when constructing the operators
*/
private void setupVariationOperators(jmetal.core.Algorithm algorithm,
TypedProperties properties, JMetalProblemAdapter problem)
throws JMException {
Operator crossover = null;
Operator mutation = null;
HashMap<String, Object> parameters = null;
SolutionType solutionType = problem.getSolutionType();
if ((solutionType instanceof BinarySolutionType)
|| (solutionType instanceof BinaryRealSolutionType)) {
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("1x.rate", 0.9));
crossover = new SinglePointCrossover(parameters);
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("bf.rate", 1.0 / problem.getLength(0)));
mutation = new BitFlipMutation(parameters);
} else if (solutionType instanceof RealSolutionType) {
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("sbx.rate", 1.0));
parameters.put("distributionIndex", properties.getDouble("sbx.distributionIndex", 15.0));
crossover = new SBXCrossover(parameters);
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("pm.rate", 1.0 / problem.getNumberOfVariables()));
parameters.put("distributionIndex", properties.getDouble("pm.distributionIndex", 20.0));
mutation = new PolynomialMutation(parameters);
} else if (solutionType instanceof PermutationSolutionType) {
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("pmx.rate", 1.0));
crossover = new PMXCrossover(parameters);
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("swap.rate", 0.35));
mutation = new SwapMutation(parameters);
} else {
throw new JMException("solution type not supported");
}
algorithm.addOperator("crossover", crossover);
algorithm.addOperator("mutation", mutation);
}
/**
* Returns a new {@link AbYSS} instance. Only real encodings are supported.
*
* @param properties the properties for customizing the new {@code AbYSS}
* instance
* @param problem the problem adapter
* @return a new {@code AbYSS} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private AbYSS newAbYSS(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
if (!(problem.getSolutionType() instanceof RealSolutionType)) {
throw new JMException("unsupported solution type");
}
AbYSS algorithm = new AbYSS(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 20));
algorithm.setInputParameter("refSet1Size",
(int)properties.getDouble("refSet1Size", 10));
algorithm.setInputParameter("refSet2Size",
(int)properties.getDouble("refSet2Size", 10));
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("sbx.rate", 1.0));
parameters.put("distributionIndex", properties.getDouble("sbx.distributionIndex", 15.0));
Operator crossover = new SBXCrossover(parameters);
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("pm.rate", 1.0 / problem.getNumberOfVariables()));
parameters.put("distributionIndex", properties.getDouble("pm.distributionIndex", 20.0));
Operator mutation = new PolynomialMutation(parameters);
parameters = new HashMap<String, Object>();
parameters.put("problem", problem);
parameters.put("improvementRounds", (int)properties.getDouble("improvementRounds", 1));
parameters.put("mutation", mutation);
Operator improvement = new MutationLocalSearch(parameters);
algorithm.addOperator("crossover", crossover);
algorithm.addOperator("improvement", improvement);
return algorithm;
}
/**
* Returns a new {@link CellDE} instance. Only real encodings are
* supported.
*
* @param properties the properties for customizing the new {@code CellDE}
* instance
* @param problem the problem adapter
* @return a new {@code CellDE} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private CellDE newCellDE(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
if (!(problem.getSolutionType() instanceof RealSolutionType)) {
throw new JMException("unsupported solution type");
}
CellDE algorithm = new CellDE(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
algorithm.setInputParameter("feedBack",
(int)properties.getDouble("feedBack", 20));
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("CR", properties.getDouble("de.crossoverRate", 0.1));
parameters.put("F", properties.getDouble("de.stepSize", 0.5));
Operator crossover = new DifferentialEvolutionCrossover(parameters);
Operator selection = new BinaryTournament(null);
algorithm.addOperator("crossover", crossover);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@link DENSEA} instance.
*
* @param properties the properties for customizing the new {@code DENSEA}
* instance
* @param problem the problem adapter
* @return a new {@code DENSEA} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private DENSEA newDENSEA(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
DENSEA algorithm = new DENSEA(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
setupVariationOperators(algorithm, properties, problem);
Operator selection = new BinaryTournament(null);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@link FastPGA} instance.
*
* @param properties the properties for customizing the new {@code FastPGA}
* instance
* @param problem the problem adapter
* @return a new {@code FastPGA} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private FastPGA newFastPGA(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
FastPGA algorithm = new FastPGA(problem);
algorithm.setInputParameter("maxPopSize",
(int)properties.getDouble("maxPopSize", 100));
algorithm.setInputParameter("initialPopulationSize",
(int)properties.getDouble("initialPopulationSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
algorithm.setInputParameter("a", properties.getDouble("a", 20.0));
algorithm.setInputParameter("b", properties.getDouble("b", 1.0));
algorithm.setInputParameter("c", properties.getDouble("c", 20.0));
algorithm.setInputParameter("d", properties.getDouble("d", 0.0));
algorithm.setInputParameter("termination",
(int)properties.getDouble("termination", 1));
setupVariationOperators(algorithm, properties, problem);
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("comparator", new FPGAFitnessComparator());
Operator selection = new BinaryTournament(parameters);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@link GDE3} instance. Only real encodings are supported.
*
* @param properties the properties for customizing the new {@code GDE3}
* instance
* @param problem the problem adapter
* @return a new {@code GDE3} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private GDE3 newGDE3(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
if (!(problem.getSolutionType() instanceof RealSolutionType)) {
throw new JMException("unsupported solution type");
}
GDE3 algorithm = new GDE3(problem);
int populationSize = (int)properties.getDouble("populationSize", 100);
algorithm.setInputParameter("populationSize", populationSize);
algorithm.setInputParameter("maxIterations", (int)properties.getDouble(
"maxEvaluations", 25000) / populationSize);
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("CR", properties.getDouble("de.crossoverRate", 0.1));
parameters.put("F", properties.getDouble("de.stepSize", 0.5));
Operator crossover = new DifferentialEvolutionCrossover(parameters);
Operator selection = new DifferentialEvolutionSelection(null);
algorithm.addOperator("crossover", crossover);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@link IBEA} instance.
*
* @param properties the properties for customizing the new {@code IBEA}
* instance
* @param problem the problem adapter
* @return a new {@code IBEA} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private IBEA newIBEA(TypedProperties properties, JMetalProblemAdapter problem)
throws JMException {
IBEA algorithm = new IBEA(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
setupVariationOperators(algorithm, properties, problem);
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("comparator", new FitnessComparator());
Operator selection = new BinaryTournament(parameters);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@code MOCell} instance.
*
* @param properties the properties for customizing the new {@code MOCell}
* instance
* @param problem the problem adapter
* @return a new {@code MOCell} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private MOCell newMOCell(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
MOCell algorithm = new MOCell(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
algorithm.setInputParameter("feedBack",
(int)properties.getDouble("feedBack", 20));
setupVariationOperators(algorithm, properties, problem);
Operator selection = new BinaryTournament(null);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@link MOCHC} instance. Only binary encodings are
* supported.
*
* @param properties the properties for customizing the new {@code MOCHC}
* instance
* @param problem the problem adapter
* @return a new {@code MOCHC} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private MOCHC newMOCHC(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
if (!(problem.getSolutionType() instanceof BinarySolutionType)) {
throw new JMException("unsupported solution type");
}
MOCHC algorithm = new MOCHC(problem);
algorithm.setInputParameter("initialConvergenceCount",
properties.getDouble("initialConvergenceCount", 0.25));
algorithm.setInputParameter("preservedPopulation",
properties.getDouble("preservedPopulation", 0.05));
algorithm.setInputParameter("convergenceValue",
(int)properties.getDouble("convergenceValue", 3));
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("hux.rate", 1.0));
Operator crossoverOperator = new HUXCrossover(parameters);
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("bf.rate", 0.35));
Operator mutationOperator = new BitFlipMutation(parameters);
Operator parentsSelection = new RandomSelection(null);
parameters = new HashMap<String, Object>();
parameters.put("problem", problem);
Operator newGenerationSelection = new RankingAndCrowdingSelection(parameters);
algorithm.addOperator("crossover", crossoverOperator);
algorithm.addOperator("cataclysmicMutation", mutationOperator);
algorithm.addOperator("parentSelection", parentsSelection);
algorithm.addOperator("newGenerationSelection", newGenerationSelection);
return algorithm;
}
private NSGAII newNSGAII(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
NSGAII algorithm = new NSGAII(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
setupVariationOperators(algorithm, properties, problem);
Operator selection = new BinaryTournament2(null);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@link OMOPSO} instance. Only real encodings are supported.
*
* @param properties the properties for customizing the new {@code OMOPSO}
* instance
* @param problem the problem adapter
* @return a new {@code OMOPSO} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private OMOPSO newOMOPSO(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
if (!(problem.getSolutionType() instanceof RealSolutionType)) {
throw new JMException("unsupported solution type");
}
OMOPSO algorithm = new OMOPSO(problem);
int populationSize = (int)properties.getDouble("populationSize", 100);
int maxIterations = (int)properties.getDouble("maxEvaluations", 25000) /
populationSize;
double mutationProbability = 1.0 / problem.getNumberOfVariables();
algorithm.setInputParameter("swarmSize", populationSize);
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("maxIterations", maxIterations);
algorithm.setInputParameter("epsilon",
properties.getDoubleArray("epsilon", new double[] {
EpsilonHelper.getEpsilon(problem.getProblem()) }));
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("mutationProbability", mutationProbability));
parameters.put("perturbation", properties.getDouble("perturbationIndex", 0.5));
Operator uniformMutation = new UniformMutation(parameters);
parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("mutationProbability", mutationProbability));
parameters.put("perturbation", properties.getDouble("perturbationIndex", 0.5));
parameters.put("maxIterations", maxIterations);
Operator nonUniformMutation = new NonUniformMutation(parameters);
algorithm.addOperator("uniformMutation", uniformMutation);
algorithm.addOperator("nonUniformMutation", nonUniformMutation);
return algorithm;
}
/**
* Returns a new {@link PAES} instanc.
*
* @param properties the properties for customizing the new {@code PAES}
* instance
* @param problem the problem adapter
* @return a new {@code PAES} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private PAES newPAES(TypedProperties properties, JMetalProblemAdapter problem)
throws JMException {
PAES algorithm = new PAES(problem);
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("biSections",
(int)properties.getDouble("bisections", 8));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
// only the mutation operator is used
setupVariationOperators(algorithm, properties, problem);
return algorithm;
}
/**
* Returns a new {@link PESA2} instance.
*
* @param properties the properties for customizing the new {@code PESA2}
* instance
* @param problem the problem adapter
* @return a new {@code PESA2} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private PESA2 newPESA2(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
PESA2 algorithm = new PESA2(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 10));
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("bisections",
(int)properties.getDouble("bisections", 8));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
setupVariationOperators(algorithm, properties, problem);
return algorithm;
}
/**
* Returns a new {@link SMPSO} instance. Only real encodings are supported.
*
* @param properties the properties for customizing the new {@code SMPSO}
* instance
* @param problem the problem adapter
* @return a new {@code SMPSO} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private SMPSO newSMPSO(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
if (!(problem.getSolutionType() instanceof RealSolutionType)) {
throw new JMException("unsupported solution type");
}
SMPSO algorithm = new SMPSO(problem);
int populationSize = (int)properties.getDouble("populationSize", 100);
int maxIterations = (int)properties.getDouble("maxEvaluations", 25000) /
populationSize;
algorithm.setInputParameter("swarmSize", populationSize);
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("maxIterations", maxIterations);
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("probability", properties.getDouble("pm.rate", 1.0 / problem.getNumberOfVariables()));
parameters.put("distributionIndex", properties.getDouble("pm.distributionIndex", 20.0));
Operator mutation = new PolynomialMutation(parameters);
algorithm.addOperator("mutation", mutation);
return algorithm;
}
/**
* Returns a new {@link SPEA2} instance.
*
* @param properties the properties for customizing the new {@code SPEA2}
* instance
* @param problem the problem adapter
* @return a new {@code SPEA2} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private SPEA2 newSPEA2(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
SPEA2 algorithm = new SPEA2(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("archiveSize",
(int)properties.getDouble("archiveSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
setupVariationOperators(algorithm, properties, problem);
Operator selection = new BinaryTournament(null);
algorithm.addOperator("selection", selection);
return algorithm;
}
/**
* Returns a new {@link SMSEMOA} instance.
*
* @param properties the properties for customizing the new {@code SMSEMOA}
* instance
* @param problem the problem adapter
* @return a new {@code SMSEMOA} instance
* @throws JMException if an error occurred when constructing the algorithm
*/
private SMSEMOA newSMSEMOA(TypedProperties properties,
JMetalProblemAdapter problem) throws JMException {
SMSEMOA algorithm = new SMSEMOA(problem);
algorithm.setInputParameter("populationSize",
(int)properties.getDouble("populationSize", 100));
algorithm.setInputParameter("maxEvaluations",
(int)properties.getDouble("maxEvaluations", 25000));
algorithm.setInputParameter("offset",
properties.getDouble("offset", 100.0));
setupVariationOperators(algorithm, properties, problem);
Operator selection = new RandomSelection(null);
algorithm.addOperator("selection", selection);
return algorithm;
}
}