From aff324fb3f72399cd7f61a45406e608ab44eb67a Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Thu, 5 Dec 2013 18:19:01 +0100 Subject: [PATCH] issue #62 --- .../core/algorithm/recreate/Inserter.java | 7 +- .../core/algorithm/state/StateManager.java | 6 ++ .../problem/solution/route/VehicleRoute.java | 21 +++-- .../core/algorithm/recreate/TestInserter.java | 76 +++++++++++++++++++ 4 files changed, 98 insertions(+), 12 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java index 61422bb3..74053f1c 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java @@ -16,6 +16,8 @@ ******************************************************************************/ package jsprit.core.algorithm.recreate; +import org.apache.log4j.Logger; + import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound; import jsprit.core.algorithm.recreate.listener.InsertionListeners; import jsprit.core.problem.job.Job; @@ -93,7 +95,7 @@ class Inserter { TourActivity pickupShipment = this.activityFactory.createPickup((Shipment)job); TourActivity deliverShipment = this.activityFactory.createDelivery((Shipment)job); if(!iData.getSelectedVehicle().isReturnToDepot()){ - if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ + if(iData.getDeliveryInsertionIndex()>=route.getActivities().size()){ setEndLocation(route,(Shipment)job); } } @@ -118,6 +120,8 @@ class Inserter { private JobInsertionHandler jobInsertionHandler; + private static Logger log = Logger.getLogger(Inserter.class); + public Inserter(InsertionListeners insertionListeners) { this.insertionListeners = insertionListeners; new DefaultTourActivityFactory(); @@ -132,6 +136,7 @@ class Inserter { if(job == null) throw new IllegalStateException("cannot insert null-job"); if(!(vehicleRoute.getVehicle().getId().toString().equals(insertionData.getSelectedVehicle().getId().toString()))){ insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle()); +// log.debug("vehicle switched from " + vehicleRoute.getVehicle().getId() + " to " + insertionData.getSelectedVehicle().getId()); vehicleRoute.setVehicle(insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime()); } jobInsertionHandler.handleJobInsertion(job, insertionData, vehicleRoute); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/StateManager.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/StateManager.java index 47fc737b..74d0cdf7 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/StateManager.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/StateManager.java @@ -22,6 +22,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.apache.log4j.Logger; + import jsprit.core.algorithm.listener.IterationStartsListener; import jsprit.core.algorithm.recreate.listener.InsertionEndsListener; import jsprit.core.algorithm.recreate.listener.InsertionListener; @@ -50,6 +52,8 @@ import jsprit.core.problem.solution.route.state.StateFactory.States; public class StateManager implements RouteAndActivityStateGetter, IterationStartsListener, RuinListener, InsertionStartsListener, JobInsertedListener, InsertionEndsListener { + private static Logger log = Logger.getLogger(StateManager.class); + private Map vehicleRouteStates = new HashMap(); private Map activityStates = new HashMap(); @@ -245,6 +249,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart @Override public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { +// log.debug("insert " + job2insert + " in " + inRoute); insertionListeners.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); for(RouteVisitor v : routeVisitors){ v.visit(inRoute); } routeActivityVisitor.visit(inRoute); @@ -273,6 +278,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart @Override public void ruinEnds(Collection routes, Collection unassignedJobs) { +// log.debug("ruin ends"); ruinListeners.ruinEnds(routes, unassignedJobs); } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java index 7044d9f3..9ed17e4c 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java @@ -280,16 +280,6 @@ public class VehicleRoute { setStartAndEnd(vehicle, vehicleDepTime); } - public void setDepartureTime(double vehicleDepTime){ - if(start == null) throw new IllegalStateException("cannot set departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); - start.setEndTime(vehicleDepTime); - } - - public double getDepartureTime(){ - if(start == null) throw new IllegalStateException("cannot get departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); - return start.getEndTime(); - } - private void setStartAndEnd(Vehicle vehicle, double vehicleDepTime) { if(!(vehicle instanceof NoVehicle)){ if(start == null && end == null){ @@ -307,7 +297,16 @@ public class VehicleRoute { } - + public void setDepartureTime(double vehicleDepTime){ + if(start == null) throw new IllegalStateException("cannot set departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); + start.setEndTime(vehicleDepTime); + } + + public double getDepartureTime(){ + if(start == null) throw new IllegalStateException("cannot get departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); + return start.getEndTime(); + } + public boolean isEmpty() { return tourActivities.isEmpty(); } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java index a9887a1b..00bbd067 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java @@ -4,11 +4,14 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import jsprit.core.algorithm.recreate.listener.InsertionListeners; +import jsprit.core.algorithm.state.UpdateEndLocationIfRouteIsOpen; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Shipment; import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.vehicle.Vehicle; +import jsprit.core.problem.vehicle.VehicleImpl; +import jsprit.core.problem.vehicle.VehicleType; import org.junit.Test; @@ -118,5 +121,78 @@ public class TestInserter { assertEquals(route.getTourActivities().getActivities().get(3).getLocationId(),shipmentToInsert.getDeliveryLocation()); assertEquals(route.getEnd().getLocationId(),shipmentToInsert.getDeliveryLocation()); } + + @Test + public void whenSwitchingVehicleAndRouteIsClosed_newStartAndEndShouldBeTheLocationOfNewVehicle(){ + Shipment shipment = mock(Shipment.class); + Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setLocationId("vehLoc").setType(mock(VehicleType.class)).build(); + Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); + //start - pick(shipment) - del(shipment) - end + Shipment shipmentToInsert = mock(Shipment.class); + when(shipmentToInsert.getDeliveryLocation()).thenReturn("delLoc"); + when(shipmentToInsert.getPickupLocation()).thenReturn("pickLoc"); + + InsertionData iData = mock(InsertionData.class); + when(iData.getPickupInsertionIndex()).thenReturn(2); + when(iData.getDeliveryInsertionIndex()).thenReturn(2); + when(iData.getSelectedVehicle()).thenReturn(newVehicle); + + Inserter inserter = new Inserter(mock(InsertionListeners.class)); + inserter.insertJob(shipmentToInsert, iData, route); + + assertEquals(newVehicle.getLocationId(),route.getEnd().getLocationId()); + } + + @Test + public void whenSwitchingVehicleAndRouteIsOpen_endLocationShouldBeTheLocationOfTheLastActivity(){ + Shipment shipment = mock(Shipment.class); + Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setLocationId("vehLoc").setType(mock(VehicleType.class)).build(); + Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); + //start - pick(shipment) - del(shipment) - end + Shipment shipmentToInsert = mock(Shipment.class); + when(shipmentToInsert.getDeliveryLocation()).thenReturn("delLoc"); + when(shipmentToInsert.getPickupLocation()).thenReturn("pickLoc"); + + InsertionData iData = mock(InsertionData.class); + when(iData.getPickupInsertionIndex()).thenReturn(2); + when(iData.getDeliveryInsertionIndex()).thenReturn(2); + when(iData.getSelectedVehicle()).thenReturn(newVehicle); + + Inserter inserter = new Inserter(mock(InsertionListeners.class)); + inserter.insertJob(shipmentToInsert, iData, route); + + assertEquals("delLoc",route.getEnd().getLocationId()); + } + + @Test + public void whenInsertingShipmentAtBeginningAndSwitchingVehicleAndRouteIsOpen_endLocationShouldBeTheLocationOfTheLastActivity(){ + Shipment shipment = mock(Shipment.class); + when(shipment.getDeliveryLocation()).thenReturn("oldShipmentDelLoc"); + Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setLocationId("vehLoc").setType(mock(VehicleType.class)).build(); + Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); + //start - pick(shipment) - del(shipment) - end + Shipment shipmentToInsert = mock(Shipment.class); + when(shipmentToInsert.getDeliveryLocation()).thenReturn("delLoc"); + when(shipmentToInsert.getPickupLocation()).thenReturn("pickLoc"); + + InsertionData iData = mock(InsertionData.class); + when(iData.getPickupInsertionIndex()).thenReturn(0); + when(iData.getDeliveryInsertionIndex()).thenReturn(0); + when(iData.getSelectedVehicle()).thenReturn(newVehicle); + + Inserter inserter = new Inserter(mock(InsertionListeners.class)); + inserter.insertJob(shipmentToInsert, iData, route); + + UpdateEndLocationIfRouteIsOpen updateEnd = new UpdateEndLocationIfRouteIsOpen(); + updateEnd.visit(route); + + assertEquals("oldShipmentDelLoc",route.getEnd().getLocationId()); + } }