diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java index 5537649e..b01bd7a5 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculator.java @@ -17,6 +17,7 @@ package jsprit.core.algorithm.recreate; import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound; +import jsprit.core.problem.Capacity; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Job; import jsprit.core.problem.solution.route.VehicleRoute; @@ -83,37 +84,40 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos } private double getDeltaAbsoluteFixCost(VehicleRoute route, Vehicle newVehicle, Job job) { - double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand(); + Capacity load = Capacity.addup(getCurrentMaxLoadInRoute(route), job.getSize()); +// double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand(); double currentFix = 0.0; if(route.getVehicle() != null){ if(!(route.getVehicle() instanceof NoVehicle)){ currentFix += route.getVehicle().getType().getVehicleCostParams().fix; } } - if(newVehicle.getCapacity() < load){ + if(!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)){ return Double.MAX_VALUE; } return newVehicle.getType().getVehicleCostParams().fix - currentFix; } private double getDeltaRelativeFixCost(VehicleRoute route, Vehicle newVehicle, Job job) { - int currentLoad = getCurrentMaxLoadInRoute(route); - double load = currentLoad + job.getCapacityDemand(); + Capacity currentLoad = getCurrentMaxLoadInRoute(route); +// int currentLoad = getCurrentMaxLoadInRoute(route); + Capacity load = Capacity.addup(currentLoad, job.getSize()); +// double load = currentLoad + job.getCapacityDemand(); double currentRelFix = 0.0; if(route.getVehicle() != null){ if(!(route.getVehicle() instanceof NoVehicle)){ - currentRelFix += route.getVehicle().getType().getVehicleCostParams().fix*currentLoad/route.getVehicle().getCapacity(); + currentRelFix += route.getVehicle().getType().getVehicleCostParams().fix * Capacity.divide(currentLoad, route.getVehicle().getType().getCapacityDimensions()); } } - if(newVehicle.getCapacity() < load){ + if(!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)){ return Double.MAX_VALUE; } - double relativeFixCost = newVehicle.getType().getVehicleCostParams().fix*(load/newVehicle.getCapacity()) - currentRelFix; + double relativeFixCost = newVehicle.getType().getVehicleCostParams().fix* (Capacity.divide(load, newVehicle.getType().getCapacityDimensions())) - currentRelFix; return relativeFixCost; } - private int getCurrentMaxLoadInRoute(VehicleRoute route) { - return (int) stateGetter.getRouteState(route, StateFactory.MAXLOAD).toDouble(); + private Capacity getCurrentMaxLoadInRoute(VehicleRoute route) { + return stateGetter.getRouteState(route, StateFactory.MAXLOAD, Capacity.class); } } 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 3b07770c..6bdd2e35 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/Capacity.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/Capacity.java @@ -67,6 +67,36 @@ public class Capacity { return capacityBuilder.build(); } + /** + * Divides every dimension of numerator capacity by the corresponding dimension of denominator capacity, + * , and averages each quotient. + * + *

If both nominator.get(i) and denominator.get(i) equal to 0, dimension i is ignored. + *

If both capacities are have only dimensions with dimensionVal=0, it returns 0.0 + * @param numerator + * @param denominator + * @return + * @throws IllegalStateException if numerator.get(i) != 0 and denominator.get(i) == 0 + */ + public static double divide(Capacity numerator, Capacity denominator){ + int nuOfDimensions = 0; + double sumQuotients = 0.0; + for(int index=0;index 0 and denominator = 0. cannot divide by 0"); + } + else if(numerator.get(index) == 0 && denominator.get(index) == 0){ + continue; + } + else{ + nuOfDimensions++; + sumQuotients += (double)numerator.get(index)/(double)denominator.get(index); + } + } + if(nuOfDimensions > 0) return sumQuotients/(double)nuOfDimensions; + return 0.0; + } + /** * Makes a deep copy of Capacity. * diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculatorTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculatorTest.java new file mode 100644 index 00000000..5492b16c --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/JobInsertionConsideringFixCostsCalculatorTest.java @@ -0,0 +1,8 @@ +package jsprit.core.algorithm.recreate; + +public class JobInsertionConsideringFixCostsCalculatorTest { + +// @Test +// public void + +} 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 86d62446..b94b79ce 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java @@ -314,4 +314,45 @@ public class CapacityTest { assertEquals(3,Capacity.max(cap1,cap2).get(2)); } + @Test + public void whenDividingTwoCapacities_itShouldReturn05(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build(); + assertEquals(0.5,Capacity.divide(cap1, cap2),0.001); + } + + @Test + public void whenDividingTwoEqualCapacities_itShouldReturn10(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build(); + assertEquals(1.0,Capacity.divide(cap1, cap2),0.001); + } + + @Test + public void whenDividingTwoCapacities_itShouldReturn00(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 0).addDimension(1, 0).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build(); + assertEquals(0.0,Capacity.divide(cap1, cap2),0.001); + } + + @Test(expected=IllegalStateException.class) + public void whenDividingByAZeroDim_itShouldThrowException(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 0).build(); + Capacity.divide(cap1, cap2); + } + + @Test + public void whenBothDimOfNominatorAndDenominatorAreZero_divisionShouldIgnoreThisDim(){ + Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(3, 0).build(); + Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).addDimension(3, 0).build(); + assertEquals(0.5,Capacity.divide(cap1, cap2),0.001); + } + + @Test + public void whenDividingZeroCaps_itShouldReturnZero(){ + Capacity cap1 = Capacity.Builder.newInstance().build(); + Capacity cap2 = Capacity.Builder.newInstance().build(); + assertEquals(0.0,Capacity.divide(cap1, cap2),0.001); + } }