321 lines
9.2 KiB
Java
321 lines
9.2 KiB
Java
import static org.junit.Assert.*;
|
|
|
|
import org.junit.Before;
|
|
import org.junit.Test;
|
|
|
|
public class RucksackProblemTest {
|
|
|
|
@Before
|
|
public void setUp() throws Exception {
|
|
PackingObject.reset();
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
// Tests for Rucksack object
|
|
|
|
@Test
|
|
public void rucksackCreation() {
|
|
int capacity = 50;
|
|
Rucksack rucksack = new Rucksack(capacity);
|
|
assertEquals(capacity, rucksack.getTotalCapacity());
|
|
assertEquals(capacity, rucksack.getAvailableCapacity());
|
|
assertEquals(0, rucksack.getTotalWeight());
|
|
assertEquals(0, rucksack.getTotalValue());
|
|
}
|
|
|
|
@Test
|
|
public void rucksackPutObjectContains() {
|
|
int weight1 = 5;
|
|
int value1 = 4;
|
|
int weight2 = 15;
|
|
int value2 = 14;
|
|
int capacity = 40;
|
|
PackingObject obj1 = new PackingObject(value1, weight1);
|
|
PackingObject obj2 = new PackingObject(value2, weight2);
|
|
Rucksack rucksack = new Rucksack(capacity);
|
|
assertFalse(rucksack.contains(obj1));
|
|
rucksack.putObject(obj1);
|
|
assertTrue(rucksack.contains(obj1));
|
|
assertEquals(weight1, rucksack.getTotalWeight());
|
|
assertEquals(value1, rucksack.getTotalValue());
|
|
assertEquals(capacity - weight1, rucksack.getAvailableCapacity());
|
|
assertFalse(rucksack.contains(obj2));
|
|
rucksack.putObject(obj2);
|
|
assertTrue(rucksack.contains(obj2));
|
|
assertEquals(weight1 + weight2, rucksack.getTotalWeight());
|
|
assertEquals(value1 + value2, rucksack.getTotalValue());
|
|
assertEquals(capacity - weight1 - weight2, rucksack.getAvailableCapacity());
|
|
try {
|
|
rucksack.putObject(obj2);
|
|
assertTrue("Adding an object already present should throw a ObjectAlreadyPresentException!", false);
|
|
} catch (ObjectAlreadyPresentException e) {
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void rucksackExceedCapacity() {
|
|
int weight1 = 5;
|
|
int value1 = 4;
|
|
int weight2 = 15;
|
|
int value2 = 14;
|
|
int capacity = 15;
|
|
PackingObject obj1 = new PackingObject(value1, weight1);
|
|
PackingObject obj2 = new PackingObject(value2, weight2);
|
|
Rucksack rucksack = new Rucksack(capacity);
|
|
rucksack.putObject(obj1);
|
|
try {
|
|
rucksack.putObject(obj2);
|
|
assertTrue("Adding an object above capacity should throw a CapacityExceededException!", false);
|
|
} catch (CapacityExceededException e) {
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void rucksackRemoveObjectContains() {
|
|
int weight1 = 5;
|
|
int value1 = 4;
|
|
int weight2 = 15;
|
|
int value2 = 14;
|
|
int capacity = 20;
|
|
PackingObject obj1 = new PackingObject(value1, weight1);
|
|
PackingObject obj2 = new PackingObject(value2, weight2);
|
|
Rucksack rucksack = new Rucksack(capacity);
|
|
rucksack.putObject(obj1);
|
|
rucksack.putObject(obj2);
|
|
rucksack.removeObject(obj2);
|
|
assertEquals(value1, rucksack.getTotalValue());
|
|
assertFalse(rucksack.contains(obj2));
|
|
try {
|
|
rucksack.removeObject(obj2);
|
|
assertTrue("Removing object not present should throw ObjectNotPresentException!", false);
|
|
} catch (ObjectNotPresentException e) {
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void rucksackCopyFrom() {
|
|
int capacity1 = 20;
|
|
PackingObject obj1 = new PackingObject(1,1);
|
|
PackingObject obj2 = new PackingObject(2,2);
|
|
Rucksack rucksack1 = new Rucksack(capacity1);
|
|
Rucksack rucksack2 = new Rucksack(5);
|
|
rucksack1.putObject(obj1);
|
|
rucksack2.copyFrom(rucksack1);
|
|
assertEquals(capacity1, rucksack2.getTotalCapacity());
|
|
assertTrue(rucksack2.contains(obj1));
|
|
|
|
rucksack1.removeObject(obj1);
|
|
assertFalse(rucksack1.contains(obj1));
|
|
assertTrue(rucksack2.contains(obj1));
|
|
|
|
rucksack2.putObject(obj2);
|
|
assertFalse(rucksack1.contains(obj2));
|
|
assertTrue(rucksack2.contains(obj2));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Tests for RucksackProblem
|
|
|
|
private int calculateValue(RucksackProblem problem, Rucksack rucksack) {
|
|
int result = 0;
|
|
for (PackingObject object : problem.getAllObjects()) {
|
|
if (rucksack.contains(object)) {
|
|
result += object.getValue();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private int calculateWeight(RucksackProblem problem, Rucksack rucksack) {
|
|
int result = 0;
|
|
for (PackingObject object : problem.getAllObjects()) {
|
|
if (rucksack.contains(object)) {
|
|
result += object.getWeight();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private PackingObject[] createPackingObjects(int[] values, int[] weights) {
|
|
PackingObject[] objects = new PackingObject[weights.length];
|
|
for (int i=0; i<weights.length; i++) {
|
|
objects[i] = new PackingObject(values[i], weights[i]);
|
|
}
|
|
return objects;
|
|
}
|
|
|
|
private RucksackProblem createProblemInstance(int[] values, int[] weights, int capacity) {
|
|
PackingObject[] objects = createPackingObjects(values, weights);
|
|
Rucksack rucksack = new Rucksack(capacity);
|
|
return new RucksackProblem(objects, rucksack);
|
|
}
|
|
|
|
private void solve(RucksackProblem problem, boolean iterative) {
|
|
if (iterative) {
|
|
problem.solveIterative();
|
|
} else {
|
|
problem.solveRecursive();
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void constructorNegativeValues(){
|
|
int[] values = {7,-5,4};
|
|
int[] weights = {5, 4,4};
|
|
int capacity = 8;
|
|
try {
|
|
createProblemInstance(values, weights, capacity);
|
|
assertTrue("IllegalArgumentException expected on negative input!", false);
|
|
} catch (IllegalArgumentException e) {
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void constructorNegativeWeights(){
|
|
int[] values = {7, 5,4};
|
|
int[] weights = {5,-4,4};
|
|
int capacity = 8;
|
|
try {
|
|
createProblemInstance(values, weights, capacity);
|
|
assertTrue("IllegalArgumentException expected on negative input!", false);
|
|
} catch (IllegalArgumentException e) {
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void solveIterativeAllObjectsPacked() {
|
|
solveAllObjectsPacked(true);
|
|
}
|
|
|
|
@Test
|
|
public void solveIterativeEmptyProblem() {
|
|
solveEmptyProblem(true);
|
|
}
|
|
|
|
@Test
|
|
public void solveIterativeOneObjectPacked() {
|
|
solveOneObjectPacked(true);
|
|
}
|
|
|
|
@Test
|
|
public void solveIterativeRucksack1() {
|
|
solveRucksack1(true);
|
|
}
|
|
|
|
@Test
|
|
public void solveIterativeRucksack2() {
|
|
solveRucksack2(true);
|
|
}
|
|
|
|
@Test
|
|
public void solveRecursiveAllObjectsPacked() {
|
|
solveAllObjectsPacked(false);
|
|
}
|
|
|
|
@Test
|
|
public void solveRecursiveEmptyProblem() {
|
|
solveEmptyProblem(false);
|
|
}
|
|
|
|
@Test
|
|
public void solveRecursiveOneObjectPacked() {
|
|
solveOneObjectPacked(false);
|
|
}
|
|
|
|
@Test
|
|
public void solveRecursiveRucksack1() {
|
|
solveRucksack1(false);
|
|
}
|
|
|
|
@Test
|
|
public void solveRecursiveRucksack2() {
|
|
solveRucksack2(false);
|
|
}
|
|
|
|
public void solveRucksack1(boolean iterative) {
|
|
int[] values = {34,11,32,100,65,33,300,55,200,37,400,32,76,50,49,19,17,28,7,4};
|
|
int[] weights = {34,11,32, 10,65,33,30, 55, 20,37, 40,32,76, 5,49,19,17,28,7,4};
|
|
int capacity = 105;
|
|
RucksackProblem problem = createProblemInstance(values, weights, capacity);
|
|
|
|
solve(problem, iterative);
|
|
|
|
Rucksack result = problem.getOptimalRucksack();
|
|
assertEquals(1050, result.getTotalValue());
|
|
assertEquals(capacity, result.getTotalWeight());
|
|
assertEquals(result.getTotalValue(), calculateValue(problem, result));
|
|
assertEquals(result.getTotalWeight(), calculateWeight(problem, result));
|
|
}
|
|
|
|
public void solveRucksack2(boolean iterative) {
|
|
int[] values = {7,5,4};
|
|
int[] weights = {5,4,4};
|
|
int capacity = 8;
|
|
RucksackProblem problem = createProblemInstance(values, weights, capacity);
|
|
|
|
solve(problem, iterative);
|
|
|
|
Rucksack result = problem.getOptimalRucksack();
|
|
assertEquals(9, result.getTotalValue());
|
|
assertEquals(8, result.getTotalWeight());
|
|
assertEquals(result.getTotalValue(), calculateValue(problem, result));
|
|
assertEquals(result.getTotalWeight(), calculateWeight(problem, result));
|
|
}
|
|
|
|
public void solveEmptyProblem(boolean iterative) {
|
|
int[] values = {};
|
|
int[] weights = {};
|
|
int capacity = 1;
|
|
RucksackProblem problem = createProblemInstance(values, weights, capacity);
|
|
|
|
solve(problem, iterative);
|
|
|
|
Rucksack result = problem.getOptimalRucksack();
|
|
|
|
assertEquals(0, result.getTotalValue());
|
|
assertEquals(0, result.getTotalWeight());
|
|
}
|
|
|
|
public void solveAllObjectsPacked(boolean iterative) {
|
|
int[] values = { 6, 5, 4, 3, 2, 1, 7, 8, 9,10};
|
|
int[] weights = { 1,10, 2, 9, 3, 8, 4, 7, 5, 6};
|
|
int capacity = 1+2+3+4+5+6+7+8+9+10;
|
|
RucksackProblem problem = createProblemInstance(values, weights, capacity);
|
|
|
|
solve(problem, iterative);
|
|
|
|
Rucksack result = problem.getOptimalRucksack();
|
|
|
|
assertEquals(capacity, result.getTotalValue());
|
|
assertEquals(capacity, result.getTotalWeight());
|
|
for (PackingObject o : problem.getAllObjects()) {
|
|
assertTrue(result.contains(o));
|
|
}
|
|
assertEquals(result.getTotalValue(), calculateValue(problem, result));
|
|
assertEquals(result.getTotalWeight(), calculateWeight(problem, result));
|
|
}
|
|
|
|
public void solveOneObjectPacked(boolean iterative) {
|
|
int[] values = { 1, 1, 1, 100, 1, 1, 1, 1, 1, 1 };
|
|
int[] weights = { 1, 1, 1, 10, 1, 1, 1, 1, 1, 1 };
|
|
int capacity = 10;
|
|
RucksackProblem problem = createProblemInstance(values, weights, capacity);
|
|
|
|
solve(problem, iterative);
|
|
|
|
Rucksack result = problem.getOptimalRucksack();
|
|
assertEquals(100, result.getTotalValue());
|
|
assertEquals(10, result.getTotalWeight());
|
|
for (PackingObject object : problem.getAllObjects()) {
|
|
if (object.getIndex() == 3) {
|
|
assertTrue(result.contains(object));
|
|
} else {
|
|
assertFalse(result.contains(object));
|
|
}
|
|
}
|
|
assertEquals(result.getTotalValue(), calculateValue(problem, result));
|
|
assertEquals(result.getTotalWeight(), calculateWeight(problem, result));
|
|
}
|
|
|
|
}
|