MOEAFramework-2.10.src.org.moeaframework.problem.RotatedProblems Maven / Gradle / Ivy
Show all versions of moeaframework Show documentation
/* 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 .
*/
package org.moeaframework.problem;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.moeaframework.core.NondominatedPopulation;
import org.moeaframework.core.Problem;
import org.moeaframework.core.spi.ProblemFactory;
import org.moeaframework.core.spi.ProblemProvider;
import org.moeaframework.util.RotationMatrixBuilder;
/**
* Problem provider for rotated problems. Supports any problem available
* through {@code ProblemProvider#getProblem(String)}. See {@link
* RotatedProblem} for details on how rotation is supported. Rotated problems
* are instantiated by providing the problem name prefixed with one of the
* following prefix patterns.
*
*
*
* Prefix Pattern
* Result
*
*
* {@code UNROT_}
* Unrotated problem
*
*
* {@code ROT_}
* Fully rotated instance, with each plane rotated by 45°
*
*
* {@code ROT(ANGLE)_}
* Fully rotated instance, with each plane rotated by {@code ANGLE}
* degrees. Use {@code RAND} for randomized rotations
*
*
* {@code ROT(K,ANGLE)_}
* {@code K} random rotation planes, each rotated by {@code ANGLE}
* degrees. Use {@code ALL} to rotate all planes
*
*
*
* As an example, rotated 2D DTLZ2 instances can be created with
* {@code "UNROT_DTLZ2_2"}, {@code "ROT_DTLZ2_2"}, {@code "ROT(30)_DTLZ2_2"}
* and {@code "ROT(10,RAND)_DTLZ2_2"}. Note that multiple calls to
* {@link #getProblem(String)} may return instances with different rotations.
*
* When comparing rotated problems against their unrotated versions, it is
* important to use the {@code UNROT_} prefix for the unrotated problem. The
* act of rotating a problem expands the decision variable ranges slightly
* (imagine a 1 x 1 square that is rotated 45 degrees; the bounding box of the
* rotated square is approximately 1.4 x 1.4). The {@code UNROT_} prefix
* ensures the unrotated version uses the same expanded decision variable ranges
* as the rotated variant.
*/
public class RotatedProblems extends ProblemProvider {
/**
* The regular expression pattern for parsing the rotation prefix.
*/
private static final Pattern PATTERN = Pattern.compile(
"^(?:(ROT)(?:\\((?:([0-9]+|ALL),)?(\\-?[0-9]+|RAND)\\))?|UNROT)_(.*)$",
Pattern.CASE_INSENSITIVE);
/**
* Constructs a problem provider for rotated problems.
*/
public RotatedProblems() {
super();
}
@Override
public Problem getProblem(String name) {
Matcher matcher = PATTERN.matcher(name);
if (matcher.matches()) {
Problem problem = ProblemFactory.getInstance().getProblem(
matcher.group(4));
RotationMatrixBuilder rotationMatrix = new RotationMatrixBuilder(
problem.getNumberOfVariables());
//if rotated, apply the requested rotations
if (matcher.group(1) != null) {
String k = matcher.group(2);
String angle = matcher.group(3);
if ((k == null) || k.equalsIgnoreCase("ALL")) {
rotationMatrix.rotateAll();
} else {
rotationMatrix.rotateK(Integer.parseInt(k));
}
if (angle == null) {
rotationMatrix.withThetas(Math.PI/4.0);
} else if (angle.equalsIgnoreCase("RAND")) {
rotationMatrix.withRandomThetas();
} else {
rotationMatrix.withThetas(Math.toRadians(
Double.parseDouble(angle)));
}
}
return new RotatedProblem(problem, rotationMatrix.create());
} else {
return null;
}
}
@Override
public NondominatedPopulation getReferenceSet(String name) {
Matcher matcher = PATTERN.matcher(name);
if (matcher.matches()) {
return ProblemFactory.getInstance().getReferenceSet(
matcher.group(4));
} else {
return null;
}
}
}