diff --git a/jsprit-core/src/main/java/jsprit/core/problem/Capacity.java b/jsprit-core/src/main/java/jsprit/core/problem/Capacity.java index 0788ae10..a5599672 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/Capacity.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/Capacity.java @@ -1,13 +1,75 @@ package jsprit.core.problem; - +/** + * Capacity with an arbitrary number of capacity-dimension. + * + *

Note that this assumes the the values of each capacity dimension can be added up and subtracted + * + * @author schroeder + * + */ public class Capacity { + + /** + * Adds up two capacities, i.e. sums up each and every capacity dimension, and returns the resulting Capacity. + * + *

Note that this assumes that capacity dimension can be added up. + * + * @param cap1 + * @param cap2 + * @return new capacity + * @throws NullPointerException if one of the args is null + + */ + public static Capacity addup(Capacity cap1, Capacity cap2){ + if(cap1==null || cap2==null) throw new NullPointerException("arguments must not be null"); + Capacity.Builder capacityBuilder= Capacity.Builder.newInstance(); + for(int i=0;icap1.getNuOfDimension() != cap2.getNuOfDimension()). + * @throws IllegalStateException if one of the capacityDimenstions has a negative value after subtracting + */ + public static Capacity subtract(Capacity cap, Capacity cap2substract){ + if(cap==null || cap2substract==null) throw new NullPointerException("arguments must not be null"); + Capacity.Builder capacityBuilder= Capacity.Builder.newInstance(); + for(int i=0;iif automatically resizes dimensions according to index, i.e. if index=7 there are 8 dimensions. + *

Note that it automatically resizes dimensions according to index, i.e. if index=7 there are 8 dimensions. + * New dimensions then are initialized with 0 * * @throw IllegalStateException if dimValue < 0 * @param index @@ -52,6 +120,11 @@ public class Capacity { } } + /** + * Builds an immutable Capacity and returns it. + * + * @return Capacity + */ public Capacity build() { return new Capacity(this); } @@ -77,12 +150,44 @@ public class Capacity { dimensions = builder.dimensions; } + /** + * Returns the number of specified capacity dimensions. + * + * @return + */ public int getNuOfDimensions(){ return dimensions.length; } + /** + * Returns value of capacity-dimension with specified index. + * + *

If capacity dimension does not exist, it returns 0 (rather than IndexOutOfBoundsException). + * + * @param index + * @return + */ public int get(int index){ - return dimensions[index]; + if(index than the corresponding dimension in toCompare. + * + * @param toCompare + * @return + * @throws NullPointerException if one of the args is null + * @throws IllegalStateException if number of capacityDimensions of this capacity and toCompare are different. + */ + public boolean isLessOrEqual(Capacity toCompare){ + if(toCompare == null) throw new NullPointerException(); + if(this.getNuOfDimensions() != toCompare.getNuOfDimensions()) throw new IllegalStateException("cap1.getNuOfDimension()="+this.getNuOfDimensions()+ + "!= cap2.getNuOfDimension()="+toCompare.getNuOfDimensions()+ ". cannot add up capacities with different dimension."); + for(int i=0;i toCompare.get(i)) return false; + } + return true; } } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java index 8747b3ea..3ddbb8c5 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java @@ -45,6 +45,11 @@ public interface Job { @Deprecated public int getCapacityDemand(); + /** + * Returns capacity of jobs which can consist of an arbitrary number of capacity dimensions. + * + * @return Capacity + */ public Capacity getCapacity(); } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java b/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java index bbb11d8c..2f969f0e 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java @@ -2,6 +2,7 @@ package jsprit.core.problem; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.Random; @@ -45,12 +46,12 @@ public class CapacityTest { assertEquals(4,cap.get(0)); } - @Test(expected=IndexOutOfBoundsException.class) - public void whenGettingIndexWhichIsHigherThanNuOfCapDimensions_throwIndexOutOfBoundsException(){ + @Test + public void whenGettingIndexWhichIsHigherThanNuOfCapDimensions_itShouldReturn0(){ Capacity.Builder capBuilder = Capacity.Builder.newInstance(); capBuilder.addDimension(0, 4); Capacity cap = capBuilder.build(); - cap.get(2); + assertEquals(0,cap.get(2)); } @Test @@ -89,5 +90,169 @@ public class CapacityTest { Capacity nullCap = Capacity.copyOf(null); assertTrue(nullCap==null); } + + @Test + public void whenAddingUpTwoOneDimensionalCapacities_itShouldReturnCorrectCapacityValues(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).build(); + Capacity result = Capacity.addup(cap1, cap2); + assertEquals(3, result.get(0)); + } + @Test + public void whenAddingUpTwoOneDimensionalCapacities_itShouldReturnCorrectNuOfDimensions(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).build(); + Capacity result = Capacity.addup(cap1, cap2); + assertEquals(1, result.getNuOfDimensions()); + } + + @Test + public void whenAddingUpTwoThreeDimensionalCapacities_itShouldReturnCorrectNuOfDimensions(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 3).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + Capacity result = Capacity.addup(cap1, cap2); + assertEquals(3, result.getNuOfDimensions()); + } + + @Test + public void whenAddingUpTwoThreeDimensionalCapacities_itShouldReturnCorrectCapValues(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 3).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + Capacity result = Capacity.addup(cap1, cap2); + assertEquals(3, result.get(0)); + assertEquals(5, result.get(1)); + assertEquals(7, result.get(2)); + } + + public void whenAddingUpTwoCapacitiesWithDifferentNuOfDimensions_itShouldAddThemCorrectly(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).build(); + Capacity result = Capacity.addup(cap1, cap2); + assertEquals(3,result.get(0)); + assertEquals(2,result.get(1)); + } + + @Test(expected=NullPointerException.class) + public void whenOneOfArgsIsNullWhenAdding_itShouldThrowException(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build(); + @SuppressWarnings("unused") + Capacity result = Capacity.addup(cap1, null); + } + + + + @Test + public void whenSubtractingTwoOneDimensionalCapacities_itShouldReturnCorrectCapacityValues(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).build(); + Capacity result = Capacity.subtract(cap2, cap1); + assertEquals(1, result.get(0)); + } + + @Test + public void whenSubtractingTwoOneDimensionalCapacities_itShouldReturnCorrectNuOfDimensions(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).build(); + Capacity result = Capacity.subtract(cap2, cap1); + assertEquals(1, result.getNuOfDimensions()); + } + + @Test + public void whenSubtractingTwoThreeDimensionalCapacities_itShouldReturnCorrectNuOfDimensions(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 3).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + Capacity result = Capacity.subtract(cap2, cap1); + assertEquals(3, result.getNuOfDimensions()); + } + + @Test + public void whenSubtractingTwoThreeDimensionalCapacities_itShouldReturnCorrectCapValues(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 3).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + Capacity result = Capacity.subtract(cap2, cap1); + assertEquals(1, result.get(0)); + assertEquals(1, result.get(1)); + assertEquals(1, result.get(2)); + } + + @Test(expected=IllegalStateException.class) + public void whenSubtractingTwoCapacitiesWithDifferentNuOfDimensions_itShouldThrowException(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).build(); + @SuppressWarnings("unused") + Capacity result = Capacity.subtract(cap2, cap1); + } + + @Test(expected=NullPointerException.class) + public void whenOneOfArgsIsNullWhenSubtracting_itShouldThrowException(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build(); + @SuppressWarnings("unused") + Capacity result = Capacity.subtract(cap1, null); + } + + @Test(expected=IllegalStateException.class) + public void whenSubtractingBiggerFromLower_itShouldReturnException(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 3).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + @SuppressWarnings("unused") + Capacity result = Capacity.subtract(cap1, cap2); + } + + @Test + public void whenOneCapIsLessThanAnother_itShouldReturnCorrectBoolean(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 3).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + assertTrue(cap1.isLessOrEqual(cap2)); + } + + @Test + public void whenOneCapIsLessThanAnother_itShouldReturnCorrectBoolean_v2(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 2).addDimension(2, 4).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + assertTrue(cap1.isLessOrEqual(cap2)); + } + + @Test + public void whenOneCapIsLessThanAnother_itShouldReturnCorrectBoolean_v3(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + assertTrue(cap1.isLessOrEqual(cap2)); + } + + @Test + public void whenOneCapIsBiggerThanAnother_itShouldReturnCorrectBoolean(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 3).addDimension(2, 4).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).addDimension(2, 4).build(); + assertFalse(cap2.isLessOrEqual(cap1)); + } + + @Test + public void whenAddingTwo_itShouldReturnCorrectCap(){ + int wheelChairSpace = 0; + int passengerSeats = 1; + Capacity cap1 = Capacity.Builder.newInstance().addDimension(wheelChairSpace, 2).addDimension(passengerSeats, 10).build(); + Capacity wheelChair = Capacity.Builder.newInstance().addDimension(wheelChairSpace, 1).build(); + Capacity passenger = Capacity.Builder.newInstance().addDimension(passengerSeats, 1).build(); + Capacity wheelChair_plus_passenger = Capacity.addup(wheelChair, passenger); + assertEquals(1,wheelChair_plus_passenger.get(wheelChairSpace)); + assertEquals(1,wheelChair_plus_passenger.get(passengerSeats)); + assertTrue(wheelChair_plus_passenger.isLessOrEqual(cap1)); + } + + @Test + public void whenAddingTwo_itShouldReturnCorrectCap_v2(){ + int wheelChairSpace = 0; + int passengerSeats = 1; + int weight = 2; + Capacity cap1 = Capacity.Builder.newInstance().addDimension(wheelChairSpace, 2).addDimension(passengerSeats, 10).addDimension(2, 100).build(); + Capacity wheelChair = Capacity.Builder.newInstance().addDimension(wheelChairSpace, 1).addDimension(weight, 80).build(); + Capacity passenger = Capacity.Builder.newInstance().addDimension(passengerSeats, 1).addDimension(weight, 30).build(); + Capacity wheelChair_plus_passenger = Capacity.addup(wheelChair, passenger); + assertEquals(1,wheelChair_plus_passenger.get(wheelChairSpace)); + assertEquals(1,wheelChair_plus_passenger.get(passengerSeats)); + assertEquals(110,wheelChair_plus_passenger.get(weight)); + assertFalse(wheelChair_plus_passenger.isLessOrEqual(cap1)); + } + }