/* 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.core;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.moeaframework.core.variable.RealVariable;
/**
* Tests the {@link Solution} class. Due to the central role of this class, many
* obvious properties are tested to ensure complete correctness.
*/
public class SolutionTest {
/**
* The shared solution used by these tests.
*/
private Solution solution;
/**
* Constructs the shared solution used by these tests.
*/
@Before
public void setUp() {
solution = new Solution(1, 2, 2);
solution.setVariable(0, new RealVariable(0.5, 0.0, 1.0));
solution.setObjective(0, 1.0);
solution.setObjective(1, 2.0);
solution.setConstraint(0, 0.0);
solution.setConstraint(1, 1.0);
solution.setAttribute("foo", "bar");
}
/**
* Removes references to shared objects so they can be garbage collected.
*/
@After
public void tearDown() {
solution = null;
}
/**
* Tests if the {@code getVariable} method returns the correct value.
*/
@Test
public void testGetVariable() {
Assert.assertEquals(1, solution.getNumberOfVariables());
Assert.assertEquals(0.5, ((RealVariable)solution.getVariable(0))
.getValue(), Settings.EPS);
}
/**
* Tests if the {@code getObjective} method returns the correct value.
*/
@Test
public void testGetObjective() {
Assert.assertEquals(2, solution.getNumberOfObjectives());
Assert.assertEquals(1.0, solution.getObjective(0), Settings.EPS);
Assert.assertEquals(2.0, solution.getObjective(1), Settings.EPS);
}
/**
* Tests if the {@code getConstraint} method returns the correct value.
*/
@Test
public void testGetConstraint() {
Assert.assertEquals(2, solution.getNumberOfConstraints());
Assert.assertEquals(0.0, solution.getConstraint(0), Settings.EPS);
Assert.assertEquals(1.0, solution.getConstraint(1), Settings.EPS);
}
/**
* Tests if the {@code setVariable} method sets the value correctly.
*/
@Test
public void testSetVariable() {
solution.setVariable(0, new RealVariable(0.75, 0.0, 1.0));
Assert.assertEquals(0.75, ((RealVariable)solution.getVariable(0))
.getValue(), Settings.EPS);
}
/**
* Tests if the {@code setObjective} method sets the value correctly.
*/
@Test
public void testSetObjective() {
solution.setObjective(1, 1.5);
Assert.assertEquals(1.5, solution.getObjective(1), Settings.EPS);
}
/**
* Tests if the {@code setConstraint} method sets the value correctly.
*/
@Test
public void testSetConstraint() {
solution.setConstraint(1, 2.0);
Assert.assertEquals(2.0, solution.getConstraint(1), Settings.EPS);
}
/**
* Tests if the {@code getObjectives} method returns the values correctly.
*/
@Test
public void testGetObjectives() {
double[] objectives = solution.getObjectives();
// returned array contains correct data
Assert.assertEquals(2, objectives.length);
Assert.assertEquals(1.0, objectives[0], Settings.EPS);
Assert.assertEquals(2.0, objectives[1], Settings.EPS);
// returned array is independent from internal state
objectives[0] = 0.0;
Assert.assertEquals(1.0, solution.getObjective(0), Settings.EPS);
}
/**
* Tests if the {@code getConstraints} method returns the values correctly.
*/
@Test
public void testGetConstraints() {
double[] constraints = solution.getConstraints();
// returned array contains correct data
Assert.assertEquals(2, constraints.length);
Assert.assertEquals(0.0, constraints[0], Settings.EPS);
Assert.assertEquals(1.0, constraints[1], Settings.EPS);
// returned array is independent from internal state
constraints[0] = 1.0;
Assert.assertEquals(0.0, solution.getConstraint(0), Settings.EPS);
}
/**
* Tests if the {@code setObjectives} method sets the values correctly.
*/
@Test
public void testSetObjectives() {
double[] objectives = new double[] { 3.0, 4.0 };
solution.setObjectives(objectives);
// stored array contains correct data
Assert.assertEquals(2, solution.getNumberOfObjectives());
Assert.assertEquals(3.0, solution.getObjective(0), Settings.EPS);
Assert.assertEquals(4.0, solution.getObjective(1), Settings.EPS);
// stored array is independent from external state
objectives[0] = 0.0;
Assert.assertEquals(3.0, solution.getObjective(0), Settings.EPS);
}
/**
* Tests if the {@code setConstraints} method sets the values correctly.
*/
@Test
public void testSetConstraints() {
double[] constraints = new double[] { 3.0, 4.0 };
solution.setConstraints(constraints);
// stored array contains correct data
Assert.assertEquals(2, solution.getNumberOfConstraints());
Assert.assertEquals(3.0, solution.getConstraint(0), Settings.EPS);
Assert.assertEquals(4.0, solution.getConstraint(1), Settings.EPS);
// stored array is independent from external state
constraints[0] = 0.0;
Assert.assertEquals(3.0, solution.getConstraint(0), Settings.EPS);
}
/**
* Tests if the {@code getAttribute} method works correctly.
*/
@Test
public void testGetAttribute() {
// get valid attribute
Assert.assertTrue(solution.hasAttribute("foo"));
Assert.assertEquals("bar", solution.getAttribute("foo"));
// fail on invalid attribute
Assert.assertFalse(solution.hasAttribute("bar"));
Assert.assertNull(solution.getAttribute("bar"));
}
/**
* Tests if the {@code setAttribute} method works correctly.
*/
@Test
public void testSetAttribute() {
// overwriting an attribute
solution.setAttribute("foo", "other");
Assert.assertEquals("other", solution.getAttribute("foo"));
// adding a new attribute
solution.setAttribute("bar", "new");
Assert.assertTrue(solution.hasAttribute("bar"));
Assert.assertEquals("new", solution.getAttribute("bar"));
// clearing attributes
solution.clearAttributes();
Assert.assertEquals(0, solution.getAttributes().size());
Assert.assertFalse(solution.hasAttribute("foo"));
Assert.assertNull(solution.getAttribute("foo"));
}
/**
* Tests if the {@code setVariable} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testSetVariableBoundsChecking1() {
solution.setVariable(2, new RealVariable(0.5, 0.0, 1.0));
}
/**
* Tests if the {@code setVariable} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testSetVariableBoundsChecking2() {
solution.setVariable(-1, new RealVariable(0.5, 0.0, 1.0));
}
/**
* Tests if the {@code getVariable} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testGetVariableBoundsChecking1() {
solution.getVariable(2);
}
/**
* Tests if the {@code getVariable} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testGetVariableBoundsChecking2() {
solution.getVariable(-1);
}
/**
* Tests if the {@code setObjective} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testSetObjectiveBoundsChecking1() {
solution.setObjective(2, 1.0);
}
/**
* Tests if the {@code setObjective} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testSetObjectiveBoundsChecking2() {
solution.setObjective(-1, 1.0);
}
/**
* Tests if the {@code getObjective} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testGetObjectiveBoundsChecking1() {
solution.getObjective(2);
}
/**
* Tests if the {@code getObjective} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testGetObjectiveBoundsChecking2() {
solution.getObjective(-1);
}
/**
* Tests if the {@code setObjectives} method correctly detects invalid
* indices.
*/
@Test(expected = IllegalArgumentException.class)
public void testSetObjectivesBoundsChecking() {
solution.setObjectives(new double[] { 0.0, 1.0, 2.0 });
}
/**
* Tests if the {@code setConstraint} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testSetConstraintBoundsChecking1() {
solution.setConstraint(2, 1.0);
}
/**
* Tests if the {@code setConstraint} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testSetConstraintBoundsChecking2() {
solution.setConstraint(-1, 1.0);
}
/**
* Tests if the {@code getConstraint} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testGetConstraintBoundsChecking1() {
solution.getConstraint(2);
}
/**
* Tests if the {@code getConstraint} method correctly detects invalid
* indices.
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testGetConstraintBoundsChecking2() {
solution.getConstraint(-1);
}
/**
* Tests if the {@code setConstraints} method correctly detects invalid
* indices.
*/
@Test(expected = IllegalArgumentException.class)
public void testSetConstraintsBoundsChecking() {
solution.setConstraints(new double[] { 0.0, 1.0, 2.0 });
}
/**
* Tests if the constructor, when given an array of objectives, correctly
* initializes the solution.
*/
@Test
public void testObjectiveConstructor() {
double[] objectives = new double[] { 1.0, 2.0 };
Solution solution = new Solution(objectives);
// correct internal state
Assert.assertEquals(0, solution.getNumberOfVariables());
Assert.assertEquals(2, solution.getNumberOfObjectives());
Assert.assertEquals(0, solution.getNumberOfConstraints());
Assert.assertEquals(0, solution.getAttributes().size());
Assert.assertEquals(1.0, solution.getObjective(0), Settings.EPS);
Assert.assertEquals(2.0, solution.getObjective(1), Settings.EPS);
// check if objectives were defensively copied
objectives[0] = 0.0;
Assert.assertEquals(1.0, solution.getObjective(0), Settings.EPS);
}
/**
* Tests if the copy constructor works correctly.
*/
@Test
public void testCopyConstructor() {
Solution copy = new Solution(solution);
// the equals method is based on object identity
Assert.assertFalse(solution.equals(copy));
Assert.assertFalse(copy.equals(solution));
// copy has the same variables
Assert.assertEquals(solution.getNumberOfVariables(), copy
.getNumberOfVariables());
for (int i = 0; i < copy.getNumberOfVariables(); i++) {
Assert.assertEquals(solution.getVariable(i), copy.getVariable(i));
}
// copy has the same objectives
Assert.assertEquals(solution.getNumberOfObjectives(), copy
.getNumberOfObjectives());
for (int i = 0; i < copy.getNumberOfObjectives(); i++) {
Assert.assertEquals(solution.getObjective(i), copy.getObjective(i),
Settings.EPS);
}
// copy has the same constraints
Assert.assertEquals(solution.getNumberOfConstraints(), copy
.getNumberOfConstraints());
for (int i = 0; i < copy.getNumberOfConstraints(); i++) {
Assert.assertEquals(solution.getConstraint(i), copy
.getConstraint(i), Settings.EPS);
}
// the copy's variables are independent from the original
((RealVariable)copy.getVariable(0)).setValue(1.0);
Assert.assertEquals(0.5, ((RealVariable)solution.getVariable(0))
.getValue(), Settings.EPS);
// the equals method works to detect the change
Assert.assertFalse(solution.equals(copy));
Assert.assertFalse(copy.equals(solution));
}
/**
* Tests if the {@code violatesConstraints} method returns {@code 0} if
* all constraints are satisfied and a non-zero value otherwise.
*/
@Test
public void testViolatesConstraints() {
Assert.assertTrue(solution.violatesConstraints());
solution.setConstraint(1, 0.0);
Assert.assertFalse(solution.violatesConstraints());
// solution with no constraints
Assert.assertFalse(new Solution(0, 0, 0).violatesConstraints());
}
}