/* 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;
import java.util.Properties;
import org.junit.Assert;
import org.moeaframework.Analyzer;
import org.moeaframework.Executor;
import org.moeaframework.core.spi.AlgorithmFactory;
/**
* Methods for comparing two algorithm implementations statistically.
*/
public abstract class AlgorithmTest {
/**
* Tests if two algorithms are statistically indifferent. The default
* {@link AlgorithmFactory} is used to create instances.
*
* @param problem the name of the problem to test
* @param algorithm1 the name of the first algorithm to test
* @param algorithm2 the name of the second algorithm to test
*/
public void test(String problem, String algorithm1, String algorithm2) {
test(problem, algorithm1, algorithm2, false,
AlgorithmFactory.getInstance());
}
/**
* Tests if two algorithms are statistically indifferent. The default
* {@link AlgorithmFactory} is used to create instances.
*
* @param problem the name of the problem to test
* @param algorithm1 the name of the first algorithm to test
* @param algorithm2 the name of the second algorithm to test
* @param allowBetterPerformance do not fail if the MOEA Framework
* algorithm exceeds the performance
*/
public void test(String problem, String algorithm1, String algorithm2,
boolean allowBetterPerformance) {
test(problem, algorithm1, algorithm2, allowBetterPerformance,
AlgorithmFactory.getInstance());
}
/**
* Tests if two algorithms are statistically indifferent.
*
* @param problem the name of the problem to test
* @param algorithm1 the name of the first algorithm to test
* @param algorithm2 the name of the second algorithm to test
* @param factory the factory used to construct the algorithms
*/
public void test(String problem, String algorithm1, String algorithm2,
AlgorithmFactory factory) {
test(problem, algorithm1, algorithm2, false, factory);
}
/**
* Tests if two algorithms are statistically indifferent.
*
* @param problem the name of the problem to test
* @param algorithm1 the name of the first algorithm to test
* @param algorithm2 the name of the second algorithm to test
* @param allowBetterPerformance do not fail if the MOEA Framework
* algorithm exceeds the performance
* @param factory the factory used to construct the algorithms
*/
public void test(String problem, String algorithm1, String algorithm2,
boolean allowBetterPerformance, AlgorithmFactory factory) {
test(problem, algorithm1, new Properties(), algorithm2,
new Properties(), allowBetterPerformance, factory);
}
/**
* Tests if two algorithms are statistically indifferent.
*
* @param problem the name of the problem to test
* @param algorithm1 the name of the first algorithm to test
* @param properties1 the properties used by the first algorithm to test
* @param algorithm2 the name of the second algorithm to test
* @param properties2 the properties used by the second algorithm to test
* @param allowBetterPerformance do not fail if the MOEA Framework
* algorithm exceeds the performance
* @param factory the factory used to construct the algorithms
*/
public void test(String problem, String algorithm1, Properties properties1,
String algorithm2, Properties properties2,
boolean allowBetterPerformance, AlgorithmFactory factory) {
Analyzer analyzer = new Analyzer()
.withProblem(problem)
.includeAllMetrics()
.showAggregate()
.showStatisticalSignificance();
Executor executor = new Executor()
.withProblem(problem)
.usingAlgorithmFactory(factory)
.distributeOnAllCores();
analyzer.addAll("A",
executor.withAlgorithm(algorithm1)
.withProperties(properties1)
.withMaxEvaluations(10000)
.runSeeds(10));
analyzer.addAll("B",
executor.withAlgorithm(algorithm2)
.withProperties(properties2)
.withMaxEvaluations(10000)
.runSeeds(10));
Analyzer.AnalyzerResults analyzerResults = analyzer.getAnalysis();
Analyzer.AlgorithmResult algorithmResult =
analyzerResults.get("A");
int indifferences = 0;
for (String indicator : algorithmResult.getIndicators()) {
indifferences += algorithmResult.get(indicator)
.getIndifferentAlgorithms().size();
}
if (indifferences < 5) {
if (allowBetterPerformance) {
int outperformance = 0;
for (String indicator : algorithmResult.getIndicators()) {
double value1 = analyzerResults.get("A")
.get(indicator).getMedian();
double value2 = analyzerResults.get("B")
.get(indicator).getMedian();
if (indicator.equals("Spacing") ||
indicator.equals("Hypervolume") ||
indicator.equals("Contribution") ||
indicator.equals("R1Indicator")) {
if (value1 >= value2) {
outperformance++;
}
} else {
if (value1 <= value2) {
outperformance++;
}
}
}
if (outperformance < 5) {
Assert.fail("algorithms show different performance");
}
} else {
Assert.fail("algorithms show statistical difference");
}
}
}
}