diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadActivityLevelConstraint.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadActivityLevelConstraint.java index 38a709b7..45898101 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadActivityLevelConstraint.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadActivityLevelConstraint.java @@ -35,37 +35,23 @@ class ServiceLoadActivityLevelConstraint implements HardActivityStateLevelConstr Capacity prevMaxLoad; if(prevAct instanceof Start){ futureMaxLoad = stateManager.getRouteState(iFacts.getRoute(), StateFactory.MAXLOAD, Capacity.class); -// futureMaxLoad = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.MAXLOAD).toDouble(); prevMaxLoad = stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING, Capacity.class); -// prevMaxLoad = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble(); } else{ futureMaxLoad = stateManager.getActivityState(prevAct, StateFactory.FUTURE_MAXLOAD, Capacity.class); -// futureMaxLoad = (int) stateManager.getActivityState(prevAct, StateFactory.FUTURE_MAXLOAD).toDouble(); prevMaxLoad = stateManager.getActivityState(prevAct, StateFactory.PAST_MAXLOAD, Capacity.class); -// prevMaxLoad = (int) stateManager.getActivityState(prevAct, StateFactory.PAST_MAXLOAD).toDouble(); } if(newAct instanceof PickupService || newAct instanceof ServiceActivity){ if(!Capacity.addup(newAct.getSize(), futureMaxLoad).isLessOrEqual(iFacts.getNewVehicle().getType().getCapacityDimensions())){ return ConstraintsStatus.NOT_FULFILLED; } -// if(newAct.getCapacityDemand() + futureMaxLoad > iFacts.getNewVehicle().getCapacity()){ -//// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=NOT_POSSIBLE"); -// return ConstraintsStatus.NOT_FULFILLED; -// } } if(newAct instanceof DeliverService){ if(!Capacity.addup(Capacity.invert(newAct.getSize()), prevMaxLoad).isLessOrEqual(iFacts.getNewVehicle().getType().getCapacityDimensions())){ return ConstraintsStatus.NOT_FULFILLED_BREAK; } -// if(Math.abs(newAct.getCapacityDemand()) + prevMaxLoad > iFacts.getNewVehicle().getCapacity()){ -//// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=NOT_POSSIBLE[break=neverBePossibleAnymore]"); -// return ConstraintsStatus.NOT_FULFILLED_BREAK; -// } - } -// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=POSSIBLE"); return ConstraintsStatus.FULFILLED; } } \ No newline at end of file diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraint.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraint.java index f8a45535..314698ab 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraint.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraint.java @@ -28,15 +28,20 @@ class ServiceLoadRouteLevelConstraint implements HardRouteStateLevelConstraint { @Override public boolean fulfilled(JobInsertionContext insertionContext) { + Capacity maxLoadAtRoute = stateManager.getRouteState(insertionContext.getRoute(), StateFactory.MAXLOAD, Capacity.class); + Capacity capacityDimensions = insertionContext.getNewVehicle().getType().getCapacityDimensions(); + if(!maxLoadAtRoute.isLessOrEqual(capacityDimensions)){ + return false; + } if(insertionContext.getJob() instanceof Delivery){ Capacity loadAtDepot = stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_BEGINNING, Capacity.class); - if(!Capacity.addup(loadAtDepot, insertionContext.getJob().getSize()).isLessOrEqual(insertionContext.getNewVehicle().getType().getCapacityDimensions())){ + if(!Capacity.addup(loadAtDepot, insertionContext.getJob().getSize()).isLessOrEqual(capacityDimensions)){ return false; } } else if(insertionContext.getJob() instanceof Pickup || insertionContext.getJob() instanceof Service){ Capacity loadAtEnd = stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_END, Capacity.class); - if(!Capacity.addup(loadAtEnd, insertionContext.getJob().getSize()).isLessOrEqual(insertionContext.getNewVehicle().getType().getCapacityDimensions())){ + if(!Capacity.addup(loadAtEnd, insertionContext.getJob().getSize()).isLessOrEqual(capacityDimensions)){ return false; } } 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 b94b79ce..f8d5cefe 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/CapacityTest.java @@ -31,7 +31,7 @@ public class CapacityTest { @Test public void whenSettingRandomNuOfCapDimension_nuOfDimensionMustBeCorrect(){ Random rand = new Random(); - int nuOfCapDimensions = rand.nextInt(100); + int nuOfCapDimensions = 1+rand.nextInt(100); Capacity.Builder capBuilder = Capacity.Builder.newInstance(); capBuilder.addDimension(nuOfCapDimensions-1, 4); Capacity cap = capBuilder.build(); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraintTest.java b/jsprit-core/src/test/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraintTest.java index 50c7ef37..90be3a14 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraintTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/constraint/ServiceLoadRouteLevelConstraintTest.java @@ -4,7 +4,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; + +import java.util.Arrays; + +import jsprit.core.algorithm.state.StateManager; import jsprit.core.problem.Capacity; +import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts; +import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Delivery; import jsprit.core.problem.job.Pickup; import jsprit.core.problem.job.Service; @@ -30,6 +37,21 @@ public class ServiceLoadRouteLevelConstraintTest { ServiceLoadRouteLevelConstraint constraint; + VehicleRoutingTransportCosts routingCosts = new AbstractForwardVehicleRoutingTransportCosts() { + + @Override + public double getTransportTime(String fromId, String toId,double departureTime, Driver driver, Vehicle vehicle) { + return 0; + } + + @Override + public double getTransportCost(String fromId, String toId,double departureTime, Driver driver, Vehicle vehicle) { + return 0; + } + }; + + StateManager stateManager; + @Before public void doBefore(){ VehicleType type = mock(VehicleType.class); @@ -43,10 +65,12 @@ public class ServiceLoadRouteLevelConstraintTest { stateGetter = mock(RouteAndActivityStateGetter.class); when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_BEGINNING, Capacity.class)).thenReturn(currentLoad); when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_END, Capacity.class)).thenReturn(currentLoad); - - - + when(stateGetter.getRouteState(route, StateFactory.MAXLOAD, Capacity.class)).thenReturn(currentLoad); + constraint = new ServiceLoadRouteLevelConstraint(stateGetter); + + stateManager = new StateManager(routingCosts); + stateManager.updateLoadStates(); } @Test @@ -204,4 +228,150 @@ public class ServiceLoadRouteLevelConstraintTest { assertTrue(constraint.fulfilled(iContext)); } + + @Test + public void whenAddingAServiceAndNewVehicleDoesNotHaveTheCapacity_itShouldReturnFalse(){ + Service service = mock(Service.class); + when(service.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).build()); + + Capacity atBeginning = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 1).build(); + Capacity atEnd = Capacity.Builder.newInstance().addDimension(0, 0).addDimension(1, 0).addDimension(2, 0).build(); + + RouteAndActivityStateGetter stateGetter = mock(RouteAndActivityStateGetter.class); + when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_BEGINNING, Capacity.class)).thenReturn(atBeginning); + when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_END, Capacity.class)).thenReturn(atEnd); + when(stateGetter.getRouteState(route, StateFactory.MAXLOAD, Capacity.class)).thenReturn(atBeginning); + + JobInsertionContext iContext = mock(JobInsertionContext.class); + when(iContext.getJob()).thenReturn(service); + when(iContext.getRoute()).thenReturn(route); + + VehicleType type = mock(VehicleType.class); + when(type.getCapacityDimensions()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 1).addDimension(2, 2).build()); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.getType()).thenReturn(type); + + when(iContext.getNewVehicle()).thenReturn(vehicle); + + ServiceLoadRouteLevelConstraint constraint = new ServiceLoadRouteLevelConstraint(stateGetter); + assertFalse(constraint.fulfilled(iContext)); + } + + @Test + public void whenAddingADeliveryAndNewVehicleDoesNotHaveTheCapacity_itShouldReturnFalse(){ + Service service = mock(Delivery.class); + when(service.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).build()); + + Capacity atBeginning = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 1).build(); + Capacity atEnd = Capacity.Builder.newInstance().addDimension(0, 0).addDimension(1, 0).addDimension(2, 0).build(); + + RouteAndActivityStateGetter stateGetter = mock(RouteAndActivityStateGetter.class); + when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_BEGINNING, Capacity.class)).thenReturn(atBeginning); + when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_END, Capacity.class)).thenReturn(atEnd); + when(stateGetter.getRouteState(route, StateFactory.MAXLOAD, Capacity.class)).thenReturn(atBeginning); + + JobInsertionContext iContext = mock(JobInsertionContext.class); + when(iContext.getJob()).thenReturn(service); + when(iContext.getRoute()).thenReturn(route); + + VehicleType type = mock(VehicleType.class); + when(type.getCapacityDimensions()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 1).addDimension(2, 2).build()); + vehicle = mock(Vehicle.class); + when(vehicle.getType()).thenReturn(type); + + when(iContext.getNewVehicle()).thenReturn(vehicle); + + ServiceLoadRouteLevelConstraint constraint = new ServiceLoadRouteLevelConstraint(stateGetter); + assertFalse(constraint.fulfilled(iContext)); + } + + @Test + public void whenAddingAPickupAndNewVehicleDoesNotHaveTheCapacity_itShouldReturnFalse(){ + Pickup service = mock(Pickup.class); + when(service.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).build()); + + Capacity atBeginning = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(2, 1).build(); + Capacity atEnd = Capacity.Builder.newInstance().addDimension(0, 0).addDimension(1, 0).addDimension(2, 0).build(); + + RouteAndActivityStateGetter stateGetter = mock(RouteAndActivityStateGetter.class); + when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_BEGINNING, Capacity.class)).thenReturn(atBeginning); + when(stateGetter.getRouteState(route, StateFactory.LOAD_AT_END, Capacity.class)).thenReturn(atEnd); + when(stateGetter.getRouteState(route, StateFactory.MAXLOAD, Capacity.class)).thenReturn(atBeginning); + + JobInsertionContext iContext = mock(JobInsertionContext.class); + when(iContext.getJob()).thenReturn(service); + when(iContext.getRoute()).thenReturn(route); + + VehicleType type = mock(VehicleType.class); + when(type.getCapacityDimensions()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 1).addDimension(2, 2).build()); + vehicle = mock(Vehicle.class); + when(vehicle.getType()).thenReturn(type); + + when(iContext.getNewVehicle()).thenReturn(vehicle); + + ServiceLoadRouteLevelConstraint constraint = new ServiceLoadRouteLevelConstraint(stateGetter); + assertFalse(constraint.fulfilled(iContext)); + } + + @Test + public void whenNewVehicleCapacityIsNotSufficiant1_returnFalse(){ + Pickup service = mock(Pickup.class); + when(service.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).build()); + + Service delivery = createDelivery("del1",3); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle); + routeBuilder.addService(delivery); + VehicleRoute route = routeBuilder.build(); + + stateManager.informInsertionStarts(Arrays.asList(route), null); + + VehicleType type = mock(VehicleType.class); + when(type.getCapacityDimensions()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).build()); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.getType()).thenReturn(type); + + JobInsertionContext iContext = mock(JobInsertionContext.class); + when(iContext.getJob()).thenReturn(service); + when(iContext.getRoute()).thenReturn(route); + when(iContext.getNewVehicle()).thenReturn(vehicle); + + assertFalse(new ServiceLoadRouteLevelConstraint(stateManager).fulfilled(iContext)); + } + + @Test + public void whenNewVehicleCapacityIsNotSufficiant2_returnFalse(){ + Pickup service = mock(Pickup.class); + when(service.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).build()); + + Service serviceInRoute = createPickup("pick1",3); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle); + routeBuilder.addService(serviceInRoute); + VehicleRoute route = routeBuilder.build(); + + stateManager.informInsertionStarts(Arrays.asList(route), null); + + VehicleType type = mock(VehicleType.class); + when(type.getCapacityDimensions()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 2).build()); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.getType()).thenReturn(type); + + JobInsertionContext iContext = mock(JobInsertionContext.class); + when(iContext.getJob()).thenReturn(service); + when(iContext.getRoute()).thenReturn(route); + when(iContext.getNewVehicle()).thenReturn(vehicle); + + assertFalse(new ServiceLoadRouteLevelConstraint(stateManager).fulfilled(iContext)); + } + + + + private Service createPickup(String string, int i) { + return Pickup.Builder.newInstance(string).addSizeDimension(0, i).setLocationId("loc").build(); + } + + private Service createDelivery(String string, int i) { + return Delivery.Builder.newInstance(string).addSizeDimension(0, i).setLocationId("loc").build(); + } + + }