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 2eb3c605..04ed5184 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 @@ -428,9 +428,9 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart UpdateLoads updateLoads = new UpdateLoads(this); addActivityVisitor(updateLoads); addListener(updateLoads); - addActivityVisitor(new UpdatePrevMaxLoad(this)); - addActivityVisitor(new UpdateMaxLoadForwardLooking(this)); - addActivityVisitor(new UpdateMaxLoad_(this)); + addActivityVisitor(new UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute(this)); + addActivityVisitor(new UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute(this)); + addActivityVisitor(new UpdateMaxCapacityUtilisationAtRoute(this)); } } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateLoads.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateLoads.java index f99d6db8..9ee3d7a0 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateLoads.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateLoads.java @@ -50,7 +50,7 @@ class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListe @Override public void visit(TourActivity act) { - currentLoad = Capacity.addup(currentLoad, act.getCapacity()); + currentLoad = Capacity.addup(currentLoad, act.getSize()); stateManager.putInternalActivityState_(act, StateFactory.LOAD, Capacity.class, currentLoad); assert currentLoad.isLessOrEqual(route.getVehicle().getType().getCapacityDimensions()) : "currentLoad at activity must not be > vehicleCapacity"; assert currentLoad.isGreaterOrEqual(Capacity.Builder.newInstance().build()) : "currentLoad at act must not be < 0 in one of the applied dimensions"; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute.java new file mode 100644 index 00000000..ad67fdb4 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute.java @@ -0,0 +1,44 @@ +package jsprit.core.algorithm.state; + +import jsprit.core.problem.Capacity; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.ActivityVisitor; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.solution.route.state.StateFactory; + +/** + * Determines and memorizes the maximum capacity utilization at each activity by looking backward in route, + * i.e. the maximum capacity utilization at previous activities. + * + * @author schroeder + * + */ +class UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute implements ActivityVisitor, StateUpdater { + + private StateManager stateManager; + + private VehicleRoute route; + + private Capacity maxLoad; + + public UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute(StateManager stateManager) { + this.stateManager = stateManager; + } + + @Override + public void begin(VehicleRoute route) { + this.route = route; + maxLoad = stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING, Capacity.class); + } + + @Override + public void visit(TourActivity act) { + maxLoad = Capacity.max(maxLoad, stateManager.getActivityState(act, StateFactory.LOAD, Capacity.class)); + stateManager.putInternalActivityState_(act, StateFactory.PAST_MAXLOAD, Capacity.class, maxLoad); + assert maxLoad.isGreaterOrEqual(Capacity.Builder.newInstance().build()) : "maxLoad can never be smaller than 0"; + assert maxLoad.isLessOrEqual(route.getVehicle().getType().getCapacityDimensions()) : "maxLoad can never be bigger than vehicleCap"; + } + + @Override + public void finish() {} +} \ No newline at end of file diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute.java new file mode 100644 index 00000000..4ac6a4df --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute.java @@ -0,0 +1,63 @@ +package jsprit.core.algorithm.state; + +import jsprit.core.problem.Capacity; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.ReverseActivityVisitor; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.solution.route.state.StateFactory; + +/** + * A {@link ReverseActivityVisitor} that looks forward in the vehicle route and determines + * the maximum capacity utilization (in terms of loads) at subsequent activities. + * + *
Assume a vehicle route with the following activity sequence {start,pickup(1,4),delivery(2,3),pickup(3,2),end} where
+ * pickup(1,2) = pickup(id,cap-demand).
+ * Future maxLoad for each activity are calculated as follows:
+ * loadAt(end)=6 (since two pickups need to be delivered to depot)
+ * pickup(3)=max(loadAt(pickup(3)), futureMaxLoad(end))=max(6,6)=6
+ * delivery(2)=max(loadAt(delivery(2),futureMaxLoad(pickup(3))=max(4,6)=6
+ * pickup(1)=max(7,6)=7
+ * start=max(7,7)=7
+ * activity (apart from start and end), the maximum capacity is determined when forward looking into the route.
+ * That is at each activity we know how much capacity is available whithout breaking future capacity constraints.
+ *
+ *
+ * @author schroeder
+ *
+ */
+class UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute implements ReverseActivityVisitor, StateUpdater {
+
+ private StateManager stateManager;
+
+ private VehicleRoute route;
+
+ private Capacity maxLoad = Capacity.Builder.newInstance().build();
+// private double maxLoad;
+
+ public UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute(StateManager stateManager) {
+ super();
+ this.stateManager = stateManager;
+ }
+
+ @Override
+ public void begin(VehicleRoute route) {
+ this.route = route;
+ maxLoad = stateManager.getRouteState(route, StateFactory.LOAD_AT_END, Capacity.class);
+// maxLoad = stateManager.getRouteState(route, StateFactory.LOAD_AT_END).toDouble();
+ }
+
+ @Override
+ public void visit(TourActivity act) {
+ maxLoad = Capacity.max(maxLoad, stateManager.getActivityState(act, StateFactory.LOAD, Capacity.class));
+// maxLoad = Math.max(maxLoad, stateManager.getActivityState(act, StateFactory.LOAD).toDouble());
+ stateManager.putInternalActivityState_(act, StateFactory.FUTURE_MAXLOAD, Capacity.class, maxLoad);
+// stateManager.putInternalActivityState(act, StateFactory.FUTURE_MAXLOAD, StateFactory.createState(maxLoad));
+ assert maxLoad.isLessOrEqual(route.getVehicle().getType().getCapacityDimensions()) : "maxLoad can in every capacity dimension never be bigger than vehicleCap";
+// assert maxLoad <= route.getVehicle().getCapacity() : "maxLoad can never be bigger than vehicleCap";
+ assert maxLoad.isGreaterOrEqual(Capacity.Builder.newInstance().build()) : "maxLoad can never be smaller than 0";
+ // assert maxLoad >= 0 : "maxLoad can never be smaller than 0";
+ }
+
+ @Override
+ public void finish() {}
+}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtRoute.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtRoute.java
new file mode 100644
index 00000000..d7899492
--- /dev/null
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxCapacityUtilisationAtRoute.java
@@ -0,0 +1,52 @@
+package jsprit.core.algorithm.state;
+
+import jsprit.core.problem.Capacity;
+import jsprit.core.problem.solution.route.VehicleRoute;
+import jsprit.core.problem.solution.route.activity.ActivityVisitor;
+import jsprit.core.problem.solution.route.activity.TourActivity;
+import jsprit.core.problem.solution.route.state.StateFactory;
+
+/**
+ * Updates load at activity level.
+ *
+ *
Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT. + * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot. + * + *
Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT + * + * @author stefan + * + */ +class UpdateMaxCapacityUtilisationAtRoute implements ActivityVisitor, StateUpdater { + + private StateManager stateManager; + + private Capacity currentLoad = Capacity.Builder.newInstance().build(); + + private VehicleRoute route; + + private Capacity maxLoad = Capacity.Builder.newInstance().build(); + + public UpdateMaxCapacityUtilisationAtRoute(StateManager stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public void begin(VehicleRoute route) { + currentLoad = stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING, Capacity.class); + maxLoad = currentLoad; + this.route = route; + } + + @Override + public void visit(TourActivity act) { + currentLoad = Capacity.addup(currentLoad, act.getSize()); + maxLoad = Capacity.max(maxLoad, currentLoad); + } + + @Override + public void finish() { + stateManager.putInternalRouteState_(route, StateFactory.MAXLOAD, Capacity.class, maxLoad); + } +} \ No newline at end of file diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxLoadForwardLooking.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxLoadForwardLooking.java deleted file mode 100644 index 97d03e7f..00000000 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxLoadForwardLooking.java +++ /dev/null @@ -1,46 +0,0 @@ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.solution.route.VehicleRoute; -import jsprit.core.problem.solution.route.activity.ReverseActivityVisitor; -import jsprit.core.problem.solution.route.activity.TourActivity; -import jsprit.core.problem.solution.route.state.StateFactory; - -/** - * A {@link ReverseActivityVisitor} that looks forward in the vehicle route and determines - * the maximum load for subsequent activities. - * - *
- * - * @author schroeder - * - */ -class UpdateMaxLoadForwardLooking implements ReverseActivityVisitor, StateUpdater { - - private StateManager stateManager; - - private VehicleRoute route; - - private double maxLoad; - - public UpdateMaxLoadForwardLooking(StateManager stateManager) { - super(); - this.stateManager = stateManager; - } - - @Override - public void begin(VehicleRoute route) { - this.route = route; - maxLoad = stateManager.getRouteState(route, StateFactory.LOAD_AT_END).toDouble(); - } - - @Override - public void visit(TourActivity act) { - maxLoad = Math.max(maxLoad, stateManager.getActivityState(act, StateFactory.LOAD).toDouble()); - stateManager.putInternalActivityState(act, StateFactory.FUTURE_MAXLOAD, StateFactory.createState(maxLoad)); - assert maxLoad <= route.getVehicle().getCapacity() : "maxLoad can never be bigger than vehicleCap"; - assert maxLoad >= 0 : "maxLoad can never be smaller than 0"; - } - - @Override - public void finish() {} -} \ No newline at end of file diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxLoad_.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxLoad_.java deleted file mode 100644 index 181ffa77..00000000 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateMaxLoad_.java +++ /dev/null @@ -1,68 +0,0 @@ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.solution.route.VehicleRoute; -import jsprit.core.problem.solution.route.activity.ActivityVisitor; -import jsprit.core.problem.solution.route.activity.TourActivity; -import jsprit.core.problem.solution.route.state.StateFactory; - -/** - * Updates load at activity level. - * - *
Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT. - * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot. - * - *
Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT - * - * @author stefan - * - */ -class UpdateMaxLoad_ implements ActivityVisitor, StateUpdater { - private StateManager stateManager; - private int currentLoad = 0; - private VehicleRoute route; - private int maxLoad = 0; - - /** - * Updates load at activity level. - * - *
Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT. - * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot. - * - *
Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT - * - * - * - *
The loads can be retrieved by
- * stateManager.getActivityState(activity,StateTypes.LOAD);
- *
- *
- * @author stefan
- *
- */
- public UpdateMaxLoad_(StateManager stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void begin(VehicleRoute route) {
- currentLoad = (int) stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING).toDouble();
- maxLoad = currentLoad;
- this.route = route;
- }
-
- @Override
- public void visit(TourActivity act) {
- currentLoad += act.getCapacityDemand();
- maxLoad = Math.max(maxLoad, currentLoad);
- assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
- assert currentLoad >= 0 : "currentLoad at act must not be < 0";
- }
-
- @Override
- public void finish() {
- stateManager.putInternalRouteState(route, StateFactory.MAXLOAD, StateFactory.createState(maxLoad));
- currentLoad = 0;
- maxLoad = 0;
- }
-}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePrevMaxLoad.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePrevMaxLoad.java
deleted file mode 100644
index ff87c2cd..00000000
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePrevMaxLoad.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package jsprit.core.algorithm.state;
-
-import jsprit.core.problem.solution.route.VehicleRoute;
-import jsprit.core.problem.solution.route.activity.ActivityVisitor;
-import jsprit.core.problem.solution.route.activity.TourActivity;
-import jsprit.core.problem.solution.route.state.StateFactory;
-
-
-class UpdatePrevMaxLoad implements ActivityVisitor, StateUpdater {
- private StateManager stateManager;
- private VehicleRoute route;
- private double currLoad;
- private double prevMaxLoad;
-
- public UpdatePrevMaxLoad(StateManager stateManager) {
- super();
- this.stateManager = stateManager;
- }
-
- @Override
- public void begin(VehicleRoute route) {
- this.route = route;
- currLoad = stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING).toDouble();
- prevMaxLoad = currLoad;
- }
-
- @Override
- public void visit(TourActivity act) {
- prevMaxLoad = Math.max(prevMaxLoad, stateManager.getActivityState(act, StateFactory.LOAD).toDouble());
- stateManager.putInternalActivityState(act, StateFactory.PAST_MAXLOAD, StateFactory.createState(prevMaxLoad));
- assert prevMaxLoad >= 0 : "maxLoad can never be smaller than 0";
- assert prevMaxLoad <= route.getVehicle().getCapacity() : "maxLoad can never be bigger than vehicleCap";
- }
-
- @Override
- public void finish() {}
-}
\ No newline at end of file
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java
index 7f5c8ebc..2380ae14 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java
@@ -23,7 +23,7 @@ public final class DeliverService implements DeliveryActivity{
this.delivery=deliveryActivity.getJob();
this.arrTime=deliveryActivity.getArrTime();
this.endTime=deliveryActivity.getEndTime();
- capacity = deliveryActivity.getCapacity();
+ capacity = deliveryActivity.getSize();
}
/**
@@ -96,7 +96,7 @@ public final class DeliverService implements DeliveryActivity{
}
@Override
- public Capacity getCapacity() {
+ public Capacity getSize() {
return capacity;
}
}
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java
index f709bb7f..6f8ec81b 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java
@@ -24,7 +24,7 @@ public final class DeliverShipment implements DeliveryActivity{
this.shipment = (Shipment) deliveryShipmentActivity.getJob();
this.arrTime = deliveryShipmentActivity.getArrTime();
this.endTime = deliveryShipmentActivity.getEndTime();
- this.capacity = deliveryShipmentActivity.getCapacity();
+ this.capacity = deliveryShipmentActivity.getSize();
}
@Override
@@ -97,7 +97,7 @@ public final class DeliverShipment implements DeliveryActivity{
}
@Override
- public Capacity getCapacity() {
+ public Capacity getSize() {
return capacity;
}
}
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java
index 22299fa7..daa73113 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java
@@ -151,7 +151,7 @@ public final class End implements TourActivity {
}
@Override
- public Capacity getCapacity() {
+ public Capacity getSize() {
return capacity;
}
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java
index b2b1c71d..806b2500 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java
@@ -98,7 +98,7 @@ public final class PickupService implements PickupActivity{
}
@Override
- public Capacity getCapacity() {
+ public Capacity getSize() {
return pickup.getSize();
}
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java
index 045d603b..534ceede 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java
@@ -93,7 +93,7 @@ public final class PickupShipment implements PickupActivity{
}
@Override
- public Capacity getCapacity() {
+ public Capacity getSize() {
return shipment.getSize();
}
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java
index f3cc9af6..cf354c18 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java
@@ -159,7 +159,7 @@ public class ServiceActivity implements JobActivity{
}
@Override
- public Capacity getCapacity() {
+ public Capacity getSize() {
return service.getSize();
}
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java
index a210aa0b..0b8bc885 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java
@@ -155,7 +155,7 @@ public final class Start implements TourActivity {
}
@Override
- public Capacity getCapacity() {
+ public Capacity getSize() {
return capacity;
}
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java
index 52df4a6c..e05e4b9e 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java
@@ -133,7 +133,7 @@ public interface TourActivity {
*
* @return capacity
*/
- public abstract Capacity getCapacity();
+ public abstract Capacity getSize();
/**
* Makes a deep copy of this activity.
diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdateCapacityUtilizationForwardLookingTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdateCapacityUtilizationForwardLookingTest.java
new file mode 100644
index 00000000..9215599d
--- /dev/null
+++ b/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdateCapacityUtilizationForwardLookingTest.java
@@ -0,0 +1,174 @@
+package jsprit.core.algorithm.state;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import jsprit.core.problem.Capacity;
+import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
+import jsprit.core.problem.driver.Driver;
+import jsprit.core.problem.job.Delivery;
+import jsprit.core.problem.job.Job;
+import jsprit.core.problem.job.Pickup;
+import jsprit.core.problem.solution.route.ReverseRouteActivityVisitor;
+import jsprit.core.problem.solution.route.RouteActivityVisitor;
+import jsprit.core.problem.solution.route.VehicleRoute;
+import jsprit.core.problem.solution.route.state.StateFactory;
+import jsprit.core.problem.vehicle.Vehicle;
+
+import org.junit.Test;
+
+public class UpdateCapacityUtilizationForwardLookingTest {
+
+ @Test
+ public void whenVehicleRouteHasPickupAndDelivery_futureMaxLoadAtEachActivityShouldBeCalculatedCorrectly(){
+ StateManager stateManager = new StateManager(mock(VehicleRoutingTransportCosts.class));
+ UpdateLoads updateLoad = new UpdateLoads(stateManager);
+ UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute updateMaxLoad = new UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute(stateManager);
+
+ RouteActivityVisitor routeActivityVisitor = new RouteActivityVisitor();
+ routeActivityVisitor.addActivityVisitor(updateLoad);
+
+ ReverseRouteActivityVisitor revRouteActivityVisitor = new ReverseRouteActivityVisitor();
+ revRouteActivityVisitor.addActivityVisitor(updateMaxLoad);
+
+ Pickup pickup = mock(Pickup.class);
+ when(pickup.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 1).build());
+
+ Delivery delivery = mock(Delivery.class);
+ when(delivery.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 10).build());
+
+ VehicleRoute route = VehicleRoute.Builder.newInstance(mock(Vehicle.class), mock(Driver.class))
+ .addService(pickup).addService(delivery).build();
+
+ updateLoad.informInsertionStarts(Arrays.asList(route), Collections.