/* 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.core.variable;
import java.util.BitSet;
import org.junit.Assert;
import org.junit.Test;
import org.moeaframework.core.Settings;
import org.moeaframework.core.Solution;
import org.moeaframework.core.Variable;
public class EncodingUtilsTest {
@Test
public void test3BitBinaryEncoding() {
BinaryVariable variable = new BinaryVariable(3);
EncodingUtils.encode(0, variable);
Assert.assertFalse(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(1, variable);
Assert.assertTrue(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(2, variable);
Assert.assertFalse(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(3, variable);
Assert.assertTrue(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(4, variable);
Assert.assertFalse(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertTrue(variable.get(2));
EncodingUtils.encode(5, variable);
Assert.assertTrue(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertTrue(variable.get(2));
EncodingUtils.encode(6, variable);
Assert.assertFalse(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertTrue(variable.get(2));
EncodingUtils.encode(7, variable);
Assert.assertTrue(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertTrue(variable.get(2));
}
@Test(expected = IllegalArgumentException.class)
public void testBinaryEncodingRangeCheck() {
BinaryVariable variable = new BinaryVariable(3);
EncodingUtils.encode(8, variable);
}
@Test(expected = IllegalArgumentException.class)
public void testBinaryEncodingValueCheck() {
BinaryVariable variable = new BinaryVariable(3);
EncodingUtils.encode(-1, variable);
}
@Test
public void test3BitBinaryDecoding() {
BinaryVariable variable = new BinaryVariable(3);
EncodingUtils.encode(0, variable);
Assert.assertEquals(0, EncodingUtils.decode(variable));
EncodingUtils.encode(1, variable);
Assert.assertEquals(1, EncodingUtils.decode(variable));
EncodingUtils.encode(2, variable);
Assert.assertEquals(2, EncodingUtils.decode(variable));
EncodingUtils.encode(3, variable);
Assert.assertEquals(3, EncodingUtils.decode(variable));
EncodingUtils.encode(4, variable);
Assert.assertEquals(4, EncodingUtils.decode(variable));
EncodingUtils.encode(5, variable);
Assert.assertEquals(5, EncodingUtils.decode(variable));
EncodingUtils.encode(6, variable);
Assert.assertEquals(6, EncodingUtils.decode(variable));
EncodingUtils.encode(7, variable);
Assert.assertEquals(7, EncodingUtils.decode(variable));
}
@Test
public void test3BitBinaryToGrayConversion() {
BinaryVariable variable = new BinaryVariable(3);
EncodingUtils.encode(0, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertFalse(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(1, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertTrue(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(2, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertTrue(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(3, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertFalse(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertFalse(variable.get(2));
EncodingUtils.encode(4, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertFalse(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertTrue(variable.get(2));
EncodingUtils.encode(5, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertTrue(variable.get(0));
Assert.assertTrue(variable.get(1));
Assert.assertTrue(variable.get(2));
EncodingUtils.encode(6, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertTrue(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertTrue(variable.get(2));
EncodingUtils.encode(7, variable);
EncodingUtils.binaryToGray(variable);
Assert.assertFalse(variable.get(0));
Assert.assertFalse(variable.get(1));
Assert.assertTrue(variable.get(2));
}
@Test
public void test3BitGrayToBinaryEncoding() {
BinaryVariable variable = new BinaryVariable(3);
EncodingUtils.encode(0, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(0, EncodingUtils.decode(variable));
EncodingUtils.encode(1, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(1, EncodingUtils.decode(variable));
EncodingUtils.encode(2, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(2, EncodingUtils.decode(variable));
EncodingUtils.encode(3, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(3, EncodingUtils.decode(variable));
EncodingUtils.encode(4, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(4, EncodingUtils.decode(variable));
EncodingUtils.encode(5, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(5, EncodingUtils.decode(variable));
EncodingUtils.encode(6, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(6, EncodingUtils.decode(variable));
EncodingUtils.encode(7, variable);
EncodingUtils.binaryToGray(variable);
EncodingUtils.grayToBinary(variable);
Assert.assertEquals(7, EncodingUtils.decode(variable));
}
@Test
public void testDoubleToBinaryEncoding() {
double lowerBound = -25.0;
double upperBound = 50.0;
int numberOfBits = 10;
RealVariable doubleVariable = new RealVariable(lowerBound, upperBound);
BinaryVariable binaryVariable = new BinaryVariable(numberOfBits);
double diff = (upperBound - lowerBound)
/ (2.0 * ((1L << numberOfBits) - 1));
for (double i = lowerBound; i <= upperBound; i += 0.333) {
doubleVariable.setValue(i);
// the first encoding/decoding can introduce error bounded by diff
EncodingUtils.encode(doubleVariable, binaryVariable);
EncodingUtils.decode(binaryVariable, doubleVariable);
double value = doubleVariable.getValue();
Assert.assertEquals(i, value, diff);
// ensure a second encoding/decoding returns the exact value
EncodingUtils.encode(doubleVariable, binaryVariable);
EncodingUtils.decode(binaryVariable, doubleVariable);
Assert.assertEquals(value, doubleVariable.getValue(), Settings.EPS);
}
}
@Test
public void testIntEncoding() {
Variable variable = EncodingUtils.newInt(3, 8);
EncodingUtils.setReal(variable, 5.25);
Assert.assertEquals(5, EncodingUtils.getInt(variable));
EncodingUtils.setReal(variable, 8.999);
Assert.assertEquals(8, EncodingUtils.getInt(variable));
}
@Test
public void testBinaryIntEncoding() {
Variable variable = EncodingUtils.newBinaryInt(3, 8);
EncodingUtils.setInt(variable, 5);
Assert.assertEquals(5, EncodingUtils.getInt(variable));
EncodingUtils.setInt(variable, 8);
Assert.assertEquals(8, EncodingUtils.getInt(variable));
}
@Test
public void testBinaryEncoding() {
Variable variable = EncodingUtils.newBinary(3);
EncodingUtils.setBinary(variable, new boolean[] { false, false, true });
BitSet bitSet = EncodingUtils.getBitSet(variable);
Assert.assertFalse(bitSet.get(0));
Assert.assertFalse(bitSet.get(1));
Assert.assertTrue(bitSet.get(2));
Assert.assertEquals(3, bitSet.length());
bitSet.flip(0);
bitSet.flip(2);
EncodingUtils.setBitSet(variable, bitSet);
boolean[] binary = EncodingUtils.getBinary(variable);
Assert.assertEquals(3, binary.length);
Assert.assertTrue(binary[0]);
Assert.assertFalse(binary[1]);
Assert.assertFalse(binary[2]);
}
@Test
public void testBooleanEncoding() {
Variable variable = EncodingUtils.newBoolean();
EncodingUtils.setBoolean(variable, true);
Assert.assertTrue(EncodingUtils.getBoolean(variable));
EncodingUtils.setBoolean(variable, false);
Assert.assertFalse(EncodingUtils.getBoolean(variable));
}
@Test
public void testPermutationEncoding() {
Variable variable = EncodingUtils.newPermutation(3);
EncodingUtils.setPermutation(variable, new int[] { 0, 2, 1 });
Assert.assertArrayEquals(new int[] { 0, 2, 1 },
EncodingUtils.getPermutation(variable));
}
@Test
public void testSubsetEncoding() {
Variable variable = EncodingUtils.newSubset(5, 10);
EncodingUtils.setSubset(variable, new int[] { 1, 3, 5, 6, 7 });
Assert.assertArrayEquals(new int[] { 1, 3, 5, 6, 7 },
EncodingUtils.getSubset(variable));
}
@Test
public void testRealArrayEncoding() {
Solution solution = new Solution(3, 1);
solution.setVariable(0, EncodingUtils.newReal(0.0, 1.0));
solution.setVariable(1, EncodingUtils.newReal(2.0, 4.0));
solution.setVariable(2, EncodingUtils.newReal(-1.0, 1.0));
EncodingUtils.setReal(solution, new double[] { 0.5, 3.0, 0.0 });
Assert.assertArrayEquals(new double[] { 0.5, 3.0, 0.0 },
EncodingUtils.getReal(solution), Settings.EPS);
Assert.assertArrayEquals(new double[] { 3.0, 0.0 },
EncodingUtils.getReal(solution, 1, 3), Settings.EPS);
Assert.assertArrayEquals(new double[] { 3.0 },
EncodingUtils.getReal(solution, 1, 2), Settings.EPS);
Assert.assertArrayEquals(new double[0],
EncodingUtils.getReal(solution, 1, 1), Settings.EPS);
EncodingUtils.setReal(solution, 1, 3, new double[] { 2.0, -1.0 });
Assert.assertArrayEquals(new double[] { 0.5, 2.0, -1.0 },
EncodingUtils.getReal(solution), Settings.EPS);
EncodingUtils.setReal(solution, 2, 3, new double[] { 1.0 });
Assert.assertArrayEquals(new double[] { 0.5, 2.0, 1.0 },
EncodingUtils.getReal(solution), Settings.EPS);
EncodingUtils.setReal(solution, 2, 2, new double[0]);
Assert.assertArrayEquals(new double[] { 0.5, 2.0, 1.0 },
EncodingUtils.getReal(solution), Settings.EPS);
}
@Test
public void testIntArrayEncoding() {
Solution solution = new Solution(3, 1);
solution.setVariable(0, EncodingUtils.newInt(0, 1));
solution.setVariable(1, EncodingUtils.newInt(2, 4));
solution.setVariable(2, EncodingUtils.newInt(-1, 1));
EncodingUtils.setInt(solution, new int[] { 0, 3, 0 });
Assert.assertArrayEquals(new int[] { 0, 3, 0 },
EncodingUtils.getInt(solution));
Assert.assertArrayEquals(new int[] { 3, 0 },
EncodingUtils.getInt(solution, 1, 3));
Assert.assertArrayEquals(new int[] { 3 },
EncodingUtils.getInt(solution, 1, 2));
Assert.assertArrayEquals(new int[0],
EncodingUtils.getInt(solution, 1, 1));
EncodingUtils.setInt(solution, 1, 3, new int[] { 2, -1 });
Assert.assertArrayEquals(new int[] { 0, 2, -1 },
EncodingUtils.getInt(solution));
EncodingUtils.setInt(solution, 2, 3, new int[] { 1 });
Assert.assertArrayEquals(new int[] { 0, 2, 1 },
EncodingUtils.getInt(solution));
EncodingUtils.setInt(solution, 2, 2, new int[0]);
Assert.assertArrayEquals(new int[] { 0, 2, 1 },
EncodingUtils.getInt(solution));
}
@Test(expected = IllegalArgumentException.class)
public void testRealInvalidType1() {
EncodingUtils.setReal(EncodingUtils.newBinary(3), 1.0);
}
@Test(expected = IllegalArgumentException.class)
public void testIntInvalidType1() {
EncodingUtils.setInt(EncodingUtils.newBinary(3), 1);
}
@Test(expected = IllegalArgumentException.class)
public void testBinaryInvalidType1() {
EncodingUtils.setBinary(EncodingUtils.newReal(0.0, 1.0),
new boolean[] { false, false, true });
}
@Test(expected = IllegalArgumentException.class)
public void testBitSetInvalidType1() {
EncodingUtils.setBitSet(EncodingUtils.newReal(0.0, 1.0), new BitSet(3));
}
@Test(expected = IllegalArgumentException.class)
public void testBooleanInvalidType1() {
EncodingUtils.setBoolean(EncodingUtils.newReal(0.0, 1.0), true);
}
@Test(expected = IllegalArgumentException.class)
public void testPermutationInvalidType1() {
EncodingUtils.setPermutation(EncodingUtils.newBinary(3),
new int[] { 0, 2, 1 });
}
@Test(expected = IllegalArgumentException.class)
public void testSubsetInvalidType1() {
EncodingUtils.setSubset(EncodingUtils.newBinary(3),
new int[] { 1, 3, 5, 6, 7 });
}
@Test(expected = IllegalArgumentException.class)
public void testRealInvalidType2() {
EncodingUtils.getReal(EncodingUtils.newBinary(3));
}
@Test(expected = IllegalArgumentException.class)
public void testIntInvalidType2() {
EncodingUtils.getInt(EncodingUtils.newBinary(3));
}
@Test(expected = IllegalArgumentException.class)
public void testBinaryInvalidType2() {
EncodingUtils.getBinary(EncodingUtils.newReal(0.0, 1.0));
}
@Test(expected = IllegalArgumentException.class)
public void testBitSetInvalidType2() {
EncodingUtils.getBitSet(EncodingUtils.newReal(0.0, 1.0));
}
@Test(expected = IllegalArgumentException.class)
public void testBooleanInvalidType2() {
EncodingUtils.getBoolean(EncodingUtils.newReal(0.0, 1.0));
}
@Test(expected = IllegalArgumentException.class)
public void testPermutationInvalidType2() {
EncodingUtils.getPermutation(EncodingUtils.newBinary(3));
}
@Test(expected = IllegalArgumentException.class)
public void testSubsetInvalidType2() {
EncodingUtils.getSubset(EncodingUtils.newBinary(3));
}
@Test(expected = IllegalArgumentException.class)
public void testBinaryInvalidNumberOfBits1() {
Variable variable = EncodingUtils.newBinary(2);
EncodingUtils.setBinary(variable, new boolean[] { false, false, true });
}
@Test(expected = IllegalArgumentException.class)
public void testBinaryInvalidNumberOfBits2() {
Variable variable = EncodingUtils.newBinary(2);
EncodingUtils.setBinary(variable, new boolean[] { false });
}
@Test(expected = IllegalArgumentException.class)
public void testBooleanInvalidNumberOfBits1() {
Variable variable = EncodingUtils.newBinary(2);
EncodingUtils.getBoolean(variable);
}
@Test(expected = IllegalArgumentException.class)
public void testBooleanInvalidNumberOfBits2() {
Variable variable = EncodingUtils.newBinary(2);
EncodingUtils.setBoolean(variable, true);
}
@Test(expected = IllegalArgumentException.class)
public void testRealArrayInvalidType1() {
Solution solution = new Solution(3, 1);
solution.setVariable(0, EncodingUtils.newReal(0.0, 1.0));
solution.setVariable(1, EncodingUtils.newBinary(2));
solution.setVariable(2, EncodingUtils.newReal(-1.0, 1.0));
EncodingUtils.setReal(solution, new double[] { 0.0, 0.0, 0.0 });
}
@Test(expected = IllegalArgumentException.class)
public void testRealArrayInvalidType2() {
Solution solution = new Solution(3, 1);
solution.setVariable(0, EncodingUtils.newReal(0.0, 1.0));
solution.setVariable(1, EncodingUtils.newBinary(2));
solution.setVariable(2, EncodingUtils.newReal(-1.0, 1.0));
EncodingUtils.getReal(solution);
}
@Test(expected = IllegalArgumentException.class)
public void testIntArrayInvalidType1() {
Solution solution = new Solution(3, 1);
solution.setVariable(0, EncodingUtils.newInt(0, 1));
solution.setVariable(1, EncodingUtils.newBinary(2));
solution.setVariable(2, EncodingUtils.newInt(-1, 1));
EncodingUtils.setInt(solution, new int[] { 0, 0, 0 });
}
@Test(expected = IllegalArgumentException.class)
public void testIntArrayInvalidType2() {
Solution solution = new Solution(3, 1);
solution.setVariable(0, EncodingUtils.newInt(0, 1));
solution.setVariable(1, EncodingUtils.newBinary(2));
solution.setVariable(2, EncodingUtils.newInt(-1, 1));
EncodingUtils.getInt(solution);
}
@Test(expected = IllegalArgumentException.class)
public void testRealArrayInvalidLength1() {
Solution solution = new Solution(2, 0);
solution.setVariable(0, EncodingUtils.newReal(0.0, 1.0));
solution.setVariable(1, EncodingUtils.newReal(0.0, 1.0));
EncodingUtils.setReal(solution, new double[] { 0.25 });
}
@Test(expected = IllegalArgumentException.class)
public void testRealArrayInvalidLength2() {
Solution solution = new Solution(2, 0);
solution.setVariable(0, EncodingUtils.newReal(0.0, 1.0));
solution.setVariable(1, EncodingUtils.newReal(0.0, 1.0));
EncodingUtils.setReal(solution, new double[] { 0.25, 0.75, 0.5 });
}
@Test(expected = IllegalArgumentException.class)
public void testIntArrayInvalidLength1() {
Solution solution = new Solution(2, 0);
solution.setVariable(0, EncodingUtils.newInt(0, 1));
solution.setVariable(1, EncodingUtils.newInt(0, 1));
EncodingUtils.setInt(solution, new int[] { 0 });
}
@Test(expected = IllegalArgumentException.class)
public void testIntArrayInvalidLength2() {
Solution solution = new Solution(2, 0);
solution.setVariable(0, EncodingUtils.newInt(0, 1));
solution.setVariable(1, EncodingUtils.newInt(0, 1));
EncodingUtils.setInt(solution, new int[] { 0, 1, 0 });
}
}