/* 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.problem;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.moeaframework.TestThresholds;
import org.moeaframework.TestUtils;
import org.moeaframework.core.Initialization;
import org.moeaframework.core.Settings;
import org.moeaframework.core.Solution;
import org.moeaframework.core.Variable;
import org.moeaframework.core.operator.RandomInitialization;
import org.moeaframework.core.variable.BinaryVariable;
import org.moeaframework.core.variable.Permutation;
import org.moeaframework.core.variable.RealVariable;
/**
* Tests the {@link ExternalProblem} class using the C/C++ executable.
*/
public class ExternalProblemWithCStdioTest {
protected File file;
protected ExternalProblem problem;
protected BufferedReader debugReader;
@Before
public void setUp() throws IOException {
file = new File("./test/org/moeaframework/problem/test_stdio.exe");
//attempt to run make if the file does not exist
if (!file.exists()) {
TestUtils.runMake(file.getParentFile());
}
TestUtils.assumeFileExists(file);
//start the process separately to intercept the error (debug) data
Process process = new ProcessBuilder(file.toString()).start();
debugReader = new BufferedReader(new InputStreamReader(
process.getErrorStream()));
problem = new ExternalProblem(process.getInputStream(),
process.getOutputStream()) {
@Override
public String getName() {
return "Test";
}
@Override
public int getNumberOfVariables() {
return 4;
}
@Override
public int getNumberOfObjectives() {
return 2;
}
@Override
public int getNumberOfConstraints() {
return 1;
}
@Override
public Solution newSolution() {
Solution solution = new Solution(4, 2, 1);
solution.setVariable(0, new RealVariable(0.0, 1.0));
solution.setVariable(1, new RealVariable(-1e26, 1e26));
solution.setVariable(2, new BinaryVariable(5));
solution.setVariable(3, new Permutation(3));
return solution;
}
};
}
@After
public void tearDown() throws IOException {
file = null;
if (problem != null) {
problem.close();
problem = null;
}
if (debugReader != null) {
debugReader.close();
debugReader = null;
}
}
@Test
public void test() throws IOException {
Initialization initialization = new RandomInitialization(problem,
TestThresholds.SAMPLES);
Solution[] solutions = initialization.initialize();
for (int i=0; i<solutions.length; i++) {
Solution solution = solutions[i];
problem.evaluate(solution);
//check objectives and constraints
Assert.assertArrayEquals(new double[] { i+1, 1e-10/(i+1) },
solution.getObjectives(), Settings.EPS);
Assert.assertArrayEquals(new double[] { 1e10*(i+1) },
solution.getConstraints(), Settings.EPS);
//check the debug stream
String debugLine = debugReader.readLine();
Assert.assertNotNull(debugLine);
String[] debugTokens = debugLine.split("\\s+");
for (int j=0; j<2; j++) {
Assert.assertEquals(
((RealVariable)solution.getVariable(j)).getValue(),
Double.parseDouble(debugTokens[j]), Settings.EPS);
}
BinaryVariable bv = ((BinaryVariable)solution.getVariable(2));
for (int j=0; j<bv.getNumberOfBits(); j++) {
Assert.assertEquals(bv.get(j) ? 1 : 0,
Integer.parseInt(debugTokens[2+j]));
}
Permutation p = ((Permutation)solution.getVariable(3));
for (int j=0; j<p.size(); j++) {
Assert.assertEquals(p.get(j),
Integer.parseInt(debugTokens[7+j]));
}
}
}
@Test(expected = ProblemException.class)
public void testError1() {
Solution solution = problem.newSolution();
solution.setVariable(2, new RealVariable(0.5, 0.0, 1.0));
problem.evaluate(solution);
}
@Test(expected = ProblemException.class)
public void testError2() {
Solution solution = problem.newSolution();
solution.setVariable(3, new RealVariable(0.5, 0.0, 1.0));
problem.evaluate(solution);
}
@Test(expected = ProblemException.class)
public void testError3() {
Solution solution = problem.newSolution();
solution.setVariable(1, new Permutation(3));
problem.evaluate(solution);
}
@Test(expected = ProblemException.class)
public void testError4() {
Solution solution = new Solution(1, 2, 1);
copy(solution, problem.newSolution(), 1);
problem.evaluate(solution);
}
@Test(expected = ProblemException.class)
public void testError5() {
Solution solution = new Solution(2, 2, 1);
copy(solution, problem.newSolution(), 2);
problem.evaluate(solution);
}
@Test(expected = ProblemException.class)
public void testError6() {
Solution solution = new Solution(3, 2, 1);
copy(solution, problem.newSolution(), 3);
problem.evaluate(solution);
}
@Test(expected = ProblemException.class)
public void testReturnLength() {
Solution solution = new Solution(4, 2, 2);
copy(solution, problem.newSolution(), 4);
problem.evaluate(solution);
}
@Test(expected = ProblemException.class)
public void testUnsupportedVariableType() {
Solution solution = new Solution(4, 2, 2);
copy(solution, problem.newSolution(), 3);
solution.setVariable(3, new Variable() {
private static final long serialVersionUID = 7614517658356868257L;
@Override
public Variable copy() {
return this;
}
});
problem.evaluate(solution);
}
protected void copy(Solution s1, Solution s2, int size) {
for (int i=0; i<size; i++) {
s1.setVariable(i, s2.getVariable(i));
}
}
}