Created
July 27, 2016 12:50
-
-
Save dhadka/9b63587cb34f3115fd05b35f0ce0cdfd to your computer and use it in GitHub Desktop.
Demonstrates creating a new operator within the MOEA Framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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/>. | |
*/ | |
import java.util.Properties; | |
import org.moeaframework.Executor; | |
import org.moeaframework.core.FrameworkException; | |
import org.moeaframework.core.NondominatedPopulation; | |
import org.moeaframework.core.PRNG; | |
import org.moeaframework.core.Problem; | |
import org.moeaframework.core.Solution; | |
import org.moeaframework.core.Variable; | |
import org.moeaframework.core.Variation; | |
import org.moeaframework.core.spi.OperatorFactory; | |
import org.moeaframework.core.spi.OperatorProvider; | |
import org.moeaframework.core.variable.BinaryVariable; | |
import org.moeaframework.core.variable.EncodingUtils; | |
import org.moeaframework.problem.AbstractProblem; | |
import org.moeaframework.util.TypedProperties; | |
/** | |
* Demonstrates how to define a new operator (in this case, we define | |
* single-point binary crossover for binary integers) in the MOEA Framework. | |
*/ | |
public class ExampleSinglePointBinaryCrossover { | |
/** | |
* Single-point crossover for binary variables. | |
*/ | |
public static class SinglePointBinaryCrossover implements Variation { | |
/** | |
* The probability of applying this operator. | |
*/ | |
private final double probability; | |
/** | |
* Constructs a single-point crossover operator for binary variables. | |
* | |
* @param probability the probability of applying this operator | |
*/ | |
public SinglePointBinaryCrossover(double probability) { | |
super(); | |
this.probability = probability; | |
} | |
@Override | |
public Solution[] evolve(Solution[] parents) { | |
Solution result1 = parents[0].copy(); | |
Solution result2 = parents[1].copy(); | |
for (int i = 0; i < result1.getNumberOfVariables(); i++) { | |
Variable variable1 = result1.getVariable(i); | |
Variable variable2 = result2.getVariable(i); | |
if ((PRNG.nextDouble() <= probability) | |
&& (variable1 instanceof BinaryVariable) | |
&& (variable2 instanceof BinaryVariable)) { | |
evolve((BinaryVariable)variable1, (BinaryVariable)variable2); | |
} | |
} | |
return new Solution[] { result1, result2 }; | |
} | |
/** | |
* Evolves the specified variables using the single point crossover | |
* operator. | |
* | |
* @param v1 the first variable | |
* @param v2 the second variable | |
*/ | |
public static void evolve(BinaryVariable v1, BinaryVariable v2) { | |
if (v1.getNumberOfBits() != v2.getNumberOfBits()) { | |
throw new FrameworkException("binary variables not same length"); | |
} | |
int crossoverPoint = PRNG.nextInt(v1.getNumberOfBits() - 1); | |
for (int i = 0; i <= crossoverPoint; i++) { | |
boolean temp = v1.get(i); | |
v1.set(i, v2.get(i)); | |
v2.set(i, temp); | |
} | |
} | |
@Override | |
public int getArity() { | |
return 2; | |
} | |
} | |
public static void main(String[] args) { | |
// First, register our new single point crossover operator with the | |
// MOEAFramework. Our operator will use the name "1xbin". | |
OperatorFactory.getInstance().addProvider(new OperatorProvider() { | |
@Override | |
public String getMutationHint(Problem problem) { | |
return null; | |
} | |
@Override | |
public String getVariationHint(Problem problem) { | |
return null; | |
} | |
@Override | |
public Variation getVariation(String name, Properties properties, | |
Problem problem) { | |
if (name.equalsIgnoreCase("1xbin")) { | |
TypedProperties typedProperties = new TypedProperties(properties); | |
return new SinglePointBinaryCrossover( | |
typedProperties.getDouble("1xbin.rate", 1.0)); | |
} else { | |
return null; | |
} | |
} | |
}); | |
// Second, lets define a simple problem using the binary integer | |
// encoding. This problem will have 1 variable and 2 objectives. | |
Problem problem = new AbstractProblem(1, 2) { | |
@Override | |
public void evaluate(Solution solution) { | |
double x = EncodingUtils.getInt(solution.getVariable(0)); | |
solution.setObjective(0, Math.pow(x, 2.0)); | |
solution.setObjective(1, Math.pow(x - 2.0, 2.0)); | |
} | |
@Override | |
public Solution newSolution() { | |
Solution solution = new Solution(1, 2); | |
solution.setVariable(0, EncodingUtils.newBinaryInt(-10, 10)); | |
return solution; | |
} | |
}; | |
// Third, use the Executor to parameterize the algorithm. Here, we | |
// assign the operator as "1xbin+bf" to use our new single-point binary | |
// crossover operator with bit flip mutation. | |
NondominatedPopulation result = new Executor() | |
.withProblem(problem) | |
.withAlgorithm("NSGAII") | |
.withProperty("operator", "1xbin+bf") | |
.withMaxEvaluations(10000) | |
.run(); | |
// Finally, display the results. There should be three solutions: | |
// (4, 0), (1, 1), and (0, 4) | |
System.out.format("Objective1 Objective2%n"); | |
for (Solution solution : result) { | |
System.out.format("%.4f %.4f%n", | |
solution.getObjective(0), | |
solution.getObjective(1)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment