From 71fbc8ad386e3c1bead9680df8def8b1680a8449 Mon Sep 17 00:00:00 2001 From: oblonski Date: Tue, 19 May 2015 22:52:59 +0200 Subject: [PATCH] event based sheduling and insertion --- .../recreate/AbstractInsertionStrategy.java | 12 ++- .../jsprit/core/algorithm/recreate/Event.java | 7 ++ .../algorithm/recreate/EventListener.java | 10 +++ .../algorithm/recreate/EventListeners.java | 23 ++++++ .../algorithm/recreate/InsertActivity.java | 42 ++++++++++ .../recreate/InsertActivityListener.java | 21 +++++ .../algorithm/recreate/InsertionData.java | 11 ++- ...nsertionConsideringFixCostsCalculator.java | 1 + .../recreate/ServiceInsertionCalculator.java | 2 + .../recreate/ShipmentInsertionCalculator.java | 3 + .../algorithm/recreate/SwitchVehicle.java | 34 ++++++++ .../recreate/SwitchVehicleListener.java | 15 ++++ .../recreate/RegretInsertionTest.java | 4 + .../test/resources/infiniteWriterV2Test.xml | 81 +++++++------------ 14 files changed, 210 insertions(+), 56 deletions(-) create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Event.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListener.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListeners.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivity.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivityListener.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicle.java create mode 100644 jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicleListener.java diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AbstractInsertionStrategy.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AbstractInsertionStrategy.java index 6784631c..dc2cf34e 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AbstractInsertionStrategy.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AbstractInsertionStrategy.java @@ -71,12 +71,15 @@ public abstract class AbstractInsertionStrategy implements InsertionStrategy{ private Inserter inserter; + private EventListeners eventListeners; + protected VehicleRoutingProblem vrp; public AbstractInsertionStrategy(VehicleRoutingProblem vrp) { this.insertionsListeners = new InsertionListeners(); this.vrp = vrp; inserter = new Inserter(insertionsListeners, vrp); + eventListeners = new EventListeners(); } public void setRandom(Random random) { @@ -111,7 +114,14 @@ public abstract class AbstractInsertionStrategy implements InsertionStrategy{ protected void insertJob(Job unassignedJob, InsertionData iData, VehicleRoute inRoute){ logger.trace("insert: [jobId=" + unassignedJob.getId() + "]" + iData ); - inserter.insertJob(unassignedJob, iData, inRoute); + insertionsListeners.informBeforeJobInsertion(unassignedJob, iData, inRoute); + if(!(inRoute.getVehicle().getId().equals(iData.getSelectedVehicle().getId()))){ + insertionsListeners.informVehicleSwitched(inRoute, inRoute.getVehicle(), iData.getSelectedVehicle()); + } + for(Event e : iData.getEvents()){ + eventListeners.inform(e); + } + insertionsListeners.informJobInserted(unassignedJob, inRoute, iData.getInsertionCost(), iData.getAdditionalTime()); } } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Event.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Event.java new file mode 100644 index 00000000..c759efa4 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Event.java @@ -0,0 +1,7 @@ +package jsprit.core.algorithm.recreate; + +/** + * Created by schroeder on 19/05/15. + */ +public interface Event { +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListener.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListener.java new file mode 100644 index 00000000..1781024b --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListener.java @@ -0,0 +1,10 @@ +package jsprit.core.algorithm.recreate; + +/** + * Created by schroeder on 19/05/15. + */ +interface EventListener { + + void inform(Event event); + +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListeners.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListeners.java new file mode 100644 index 00000000..069bb1b3 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/EventListeners.java @@ -0,0 +1,23 @@ +package jsprit.core.algorithm.recreate; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by schroeder on 19/05/15. + */ +class EventListeners { + + private List listeners = new ArrayList(); + + public EventListeners() { + listeners.add(new InsertActivityListener()); + listeners.add(new SwitchVehicleListener()); + } + + public void inform(Event event){ + for(EventListener l : listeners){ + l.inform(event); + } + } +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivity.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivity.java new file mode 100644 index 00000000..a14c8c1b --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivity.java @@ -0,0 +1,42 @@ +package jsprit.core.algorithm.recreate; + +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.vehicle.Vehicle; + +/** + * Created by schroeder on 19/05/15. + */ +class InsertActivity implements Event { + + private VehicleRoute vehicleRoute; + + private Vehicle newVehicle; + + private TourActivity activity; + + private int index; + + public InsertActivity(VehicleRoute vehicleRoute, Vehicle newVehicle, TourActivity activity, int index) { + this.vehicleRoute = vehicleRoute; + this.newVehicle = newVehicle; + this.activity = activity; + this.index = index; + } + + public Vehicle getNewVehicle() { + return newVehicle; + } + + public VehicleRoute getVehicleRoute() { + return vehicleRoute; + } + + public TourActivity getActivity() { + return activity; + } + + public int getIndex() { + return index; + } +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivityListener.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivityListener.java new file mode 100644 index 00000000..a9720348 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertActivityListener.java @@ -0,0 +1,21 @@ +package jsprit.core.algorithm.recreate; + +/** + * Created by schroeder on 19/05/15. + */ +class InsertActivityListener implements EventListener { + + @Override + public void inform(Event event) { + if(event instanceof InsertActivity){ + InsertActivity insertActivity = (InsertActivity) event; + if(!insertActivity.getNewVehicle().isReturnToDepot()){ + if(insertActivity.getIndex()>=insertActivity.getVehicleRoute().getActivities().size()){ + insertActivity.getVehicleRoute().getEnd().setLocation(insertActivity.getActivity().getLocation()); + } + } + insertActivity.getVehicleRoute().getTourActivities().addActivity(insertActivity.getIndex(),((InsertActivity) event).getActivity()); + } + } + +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionData.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionData.java index dbeb6e45..2c72aebe 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionData.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionData.java @@ -19,6 +19,9 @@ package jsprit.core.algorithm.recreate; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.vehicle.Vehicle; +import java.util.ArrayList; +import java.util.List; + /** * Data object that collects insertion information. It collects insertionCosts, insertionIndeces, vehicle and driver to be employed * and departureTime of vehicle at vehicle's start location (e.g. depot). @@ -65,7 +68,13 @@ public class InsertionData { private double departureTime; private double additionalTime; - + + private List events = new ArrayList(); + + List getEvents(){ + return events; + } + /** * @return the additionalTime */ 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 369d3aec..431e1b4d 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 @@ -62,6 +62,7 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos double totalInsertionCost = iData.getInsertionCost() + fixcost_contribution; InsertionData insertionData = new InsertionData(totalInsertionCost, iData.getPickupInsertionIndex(), iData.getDeliveryInsertionIndex(), newVehicle, newDriver); insertionData.setVehicleDepartureTime(newVehicleDepartureTime); + insertionData.getEvents().addAll(iData.getEvents()); return insertionData; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java index d36afb3b..ba343286 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java @@ -155,6 +155,8 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{ return InsertionData.createEmptyInsertionData(); } InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver); + insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,deliveryAct2Insert,insertionIndex)); + insertionData.getEvents().add(new SwitchVehicle(currentRoute,newVehicle,newVehicleDepartureTime)); insertionData.setVehicleDepartureTime(newVehicleDepartureTime); return insertionData; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java index 2f311725..897e198b 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java @@ -225,6 +225,9 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{ } InsertionData insertionData = new InsertionData(bestCost, pickupInsertionIndex, deliveryInsertionIndex, newVehicle, newDriver); insertionData.setVehicleDepartureTime(newVehicleDepartureTime); + insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,deliverShipment,deliveryInsertionIndex)); + insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,pickupShipment,pickupInsertionIndex)); + insertionData.getEvents().add(new SwitchVehicle(currentRoute,newVehicle,newVehicleDepartureTime)); return insertionData; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicle.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicle.java new file mode 100644 index 00000000..48d5a1ea --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicle.java @@ -0,0 +1,34 @@ +package jsprit.core.algorithm.recreate; + +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.vehicle.Vehicle; + +/** + * Created by schroeder on 19/05/15. + */ +class SwitchVehicle implements Event { + + private VehicleRoute route; + + private Vehicle vehicle; + + private double departureTime; + + public SwitchVehicle(VehicleRoute route, Vehicle vehicle, double departureTime) { + this.route = route; + this.vehicle = vehicle; + this.departureTime = departureTime; + } + + public VehicleRoute getRoute() { + return route; + } + + public Vehicle getVehicle() { + return vehicle; + } + + public double getDepartureTime() { + return departureTime; + } +} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicleListener.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicleListener.java new file mode 100644 index 00000000..cdb8d9a4 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/SwitchVehicleListener.java @@ -0,0 +1,15 @@ +package jsprit.core.algorithm.recreate; + +/** + * Created by schroeder on 19/05/15. + */ +class SwitchVehicleListener implements EventListener{ + + @Override + public void inform(Event event) { + if(event instanceof SwitchVehicle){ + SwitchVehicle switchVehicle = (SwitchVehicle) event; + switchVehicle.getRoute().setVehicleAndDepartureTime(switchVehicle.getVehicle(),((SwitchVehicle) event).getDepartureTime()); + } + } +} diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java index 8f88e146..c9870a6d 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java @@ -168,6 +168,8 @@ public class RegretInsertionTest { if(currentRoute.isEmpty()){ double mc = getCost(service.getLocation(), vehicle.getStartLocation()); iData = new InsertionData(2*mc,-1,0,vehicle,newDriver); + iData.getEvents().add(new InsertActivity(currentRoute,vehicle,vrp.copyAndGetActivities(newJob).get(0),0)); + iData.getEvents().add(new SwitchVehicle(currentRoute,vehicle,newVehicleDepartureTime)); } else { double best = Double.MAX_VALUE; @@ -189,6 +191,8 @@ public class RegretInsertionTest { bestIndex = index; } iData = new InsertionData(best,-1,bestIndex,vehicle,newDriver); + iData.getEvents().add(new InsertActivity(currentRoute,vehicle,vrp.copyAndGetActivities(newJob).get(0),bestIndex)); + iData.getEvents().add(new SwitchVehicle(currentRoute,vehicle,newVehicleDepartureTime)); } return iData; } diff --git a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml index 2d9058ab..07c5406a 100644 --- a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml +++ b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml @@ -2,9 +2,24 @@ - INFINITE + FINITE + + v2 + vehType2 + + loc + + + loc + + + 0.0 + 1.7976931348623157E308 + + true + v1 vehType @@ -33,58 +48,16 @@ + + vehType2 + + 200 + + + 0.0 + 1.0 + + + - - - - loc - - - 1 - - 2.0 - - - 0.0 - 1.7976931348623157E308 - - - - - - loc2 - - - 1 - - 4.0 - - - 0.0 - 1.7976931348623157E308 - - - - - - - 10.0 - - - noDriver - v1 - 0.0 - - 1 - 0.0 - 0.0 - - 0.0 - - - - - - -