From 614b8b5e0110fc78984ca37e0b1b06f6d516a190 Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 6 Mar 2018 12:03:21 +0200 Subject: [PATCH 1/7] state manager use vehicle index --- .../core/algorithm/state/StateManager.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java index 9d9fbb63..3dfaeb3f 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java @@ -252,7 +252,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart */ public boolean hasActivityState(TourActivity act, Vehicle vehicle, StateId stateId) { if (act.getIndex() == 0) throw new IllegalStateException("activity index is 0. this should not be."); - return vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] != null; + return vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()] != null; } /** @@ -275,9 +275,9 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart if (act.getIndex() < 0) return null; //act.getIndex() < 0 indicates that act is either Start (-1) or End (-2) T state; try { - state = type.cast(vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); + state = type.cast(vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()]); } catch (ClassCastException e) { - Object state_class = vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]; + Object state_class = vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()]; throw getClassCastException(e, stateId, type.toString(), state_class.getClass().toString()); } return state; @@ -333,8 +333,8 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart @SuppressWarnings("UnusedDeclaration") public boolean hasRouteState(VehicleRoute route, Vehicle vehicle, StateId stateId) { if (!vehicleDependentRouteStateMap.containsKey(route)) return false; - return vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] != null; -// return vehicle_dependent_route_states[route.getActivities().get(0).getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] != null; + return vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()] != null; +// return vehicle_dependent_route_states[route.getActivities().get(0).getIndex()][vehicle.getIndex()][stateId.getIndex()] != null; } /** @@ -355,18 +355,18 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart T state = null; if(isIndexedBased){ try { - state = type.cast(vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); + state = type.cast(vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getIndex()][stateId.getIndex()]); } catch (ClassCastException e) { - throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()].getClass().toString()); + throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getIndex()][stateId.getIndex()].getClass().toString()); } } else { try { if (vehicleDependentRouteStateMap.containsKey(route)) { - state = type.cast(vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); + state = type.cast(vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()]); } } catch (ClassCastException e) { - throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()].getClass().toString()); + throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()].getClass().toString()); } } return state; @@ -422,7 +422,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart } void putInternalTypedActivityState(TourActivity act, Vehicle vehicle, StateId stateId, T state) { - vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] = state; + vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()] = state; } /** @@ -473,13 +473,13 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart void putTypedInternalRouteState(VehicleRoute route, Vehicle vehicle, StateId stateId, T state) { if (route.isEmpty()) return; if(isIndexedBased){ - vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] = state; + vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getIndex()][stateId.getIndex()] = state; } else { if (!vehicleDependentRouteStateMap.containsKey(route)) { vehicleDependentRouteStateMap.put(route, new Object[nuVehicleTypeKeys][stateIndexCounter]); } - vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] = state; + vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()] = state; } } From afead682433cec6e52d2ea78bacbafd1997a4372 Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 6 Mar 2018 13:40:35 +0200 Subject: [PATCH 2/7] Update max time in vehicle use vehicle index --- .../algorithm/state/UpdateMaxTimeInVehicle.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java index 9ae37d36..a5659c14 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java @@ -93,7 +93,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ vehicles = vehiclesToUpdate.get(route); this.route = route; for(Vehicle v : vehicles){ - int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); + int vehicleIndex = v.getIndex(); openPickupEndTimesPerVehicle.put(vehicleIndex, new HashMap()); slackTimesPerVehicle.put(vehicleIndex, new HashMap()); actStartTimesPerVehicle.put(vehicleIndex, new HashMap()); @@ -108,10 +108,10 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ double maxTime = getMaxTimeInVehicle(activity); for(Vehicle v : vehicles) { - int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); + int vehicleIndex = v.getIndex(); Location prevActLocation = prevActLocations[vehicleIndex]; - double prevActEndTime = prevActEndTimes[v.getVehicleTypeIdentifier().getIndex()]; - double activityArrival = prevActEndTimes[v.getVehicleTypeIdentifier().getIndex()] + transportTime.getTransportTime(prevActLocation,activity.getLocation(),prevActEndTime,route.getDriver(),v); + double prevActEndTime = prevActEndTimes[v.getIndex()]; + double activityArrival = prevActEndTimes[v.getIndex()] + transportTime.getTransportTime(prevActLocation,activity.getLocation(),prevActEndTime,route.getDriver(),v); double activityStart = Math.max(activityArrival,activity.getTheoreticalEarliestOperationStartTime()); memorizeActStart(activity,v,activityStart); double activityEnd = activityStart + activityCosts.getActivityDuration(prevTourActivity, activity, activityArrival, route.getDriver(), v); @@ -145,13 +145,13 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ } private void memorizeActStart(TourActivity activity, Vehicle v, double activityStart) { - actStartTimesPerVehicle.get(v.getVehicleTypeIdentifier().getIndex()).put(activity, activityStart); + actStartTimesPerVehicle.get(v.getIndex()).put(activity, activityStart); } @Override public void finish() { for(Vehicle v : vehicles) { - int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); + int vehicleIndex = v.getIndex(); //!!! open routes !!! double routeEnd; @@ -194,7 +194,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ public void finish(List activities, Job ignore) { for (Vehicle v : vehicles) { - int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); + int vehicleIndex = v.getIndex(); //!!! open routes !!! double routeEnd; @@ -236,7 +236,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ } private double actStart(TourActivity act, Vehicle v) { - return actStartTimesPerVehicle.get(v.getVehicleTypeIdentifier().getIndex()).get(act); + return actStartTimesPerVehicle.get(v.getIndex()).get(act); } private double minSlackTime(Map openDeliveries) { From 4e8ed3a9c09472ef97eb09fed96857649fed0cbe Mon Sep 17 00:00:00 2001 From: Iris Date: Tue, 6 Mar 2018 16:20:30 +0200 Subject: [PATCH 3/7] max time in vehicle fix --- .../core/algorithm/state/StateManager.java | 28 +- .../state/UpdateMaxTimeInVehicle.java | 16 +- .../MaxTimeInVehicleConstraint.java | 6 +- .../core/algorithm/MaxTimeInVehicleTest.java | 340 ++++++++++++++++++ 4 files changed, 367 insertions(+), 23 deletions(-) create mode 100644 jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java index 3dfaeb3f..05eaa321 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java @@ -252,7 +252,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart */ public boolean hasActivityState(TourActivity act, Vehicle vehicle, StateId stateId) { if (act.getIndex() == 0) throw new IllegalStateException("activity index is 0. this should not be."); - return vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()] != null; + return vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] != null; } /** @@ -275,9 +275,9 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart if (act.getIndex() < 0) return null; //act.getIndex() < 0 indicates that act is either Start (-1) or End (-2) T state; try { - state = type.cast(vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()]); + state = type.cast(vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); } catch (ClassCastException e) { - Object state_class = vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()]; + Object state_class = vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]; throw getClassCastException(e, stateId, type.toString(), state_class.getClass().toString()); } return state; @@ -333,8 +333,8 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart @SuppressWarnings("UnusedDeclaration") public boolean hasRouteState(VehicleRoute route, Vehicle vehicle, StateId stateId) { if (!vehicleDependentRouteStateMap.containsKey(route)) return false; - return vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()] != null; -// return vehicle_dependent_route_states[route.getActivities().get(0).getIndex()][vehicle.getIndex()][stateId.getIndex()] != null; + return vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] != null; +// return vehicle_dependent_route_states[route.getActivities().get(0).getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] != null; } /** @@ -355,18 +355,18 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart T state = null; if(isIndexedBased){ try { - state = type.cast(vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getIndex()][stateId.getIndex()]); + state = type.cast(vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); } catch (ClassCastException e) { - throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getIndex()][stateId.getIndex()].getClass().toString()); + throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()].getClass().toString()); } } else { try { if (vehicleDependentRouteStateMap.containsKey(route)) { - state = type.cast(vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()]); + state = type.cast(vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]); } } catch (ClassCastException e) { - throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()].getClass().toString()); + throw getClassCastException(e, stateId, type.toString(), vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()].getClass().toString()); } } return state; @@ -422,7 +422,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart } void putInternalTypedActivityState(TourActivity act, Vehicle vehicle, StateId stateId, T state) { - vehicleDependentActivityStates[act.getIndex()][vehicle.getIndex()][stateId.getIndex()] = state; + vehicleDependentActivityStates[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] = state; } /** @@ -449,10 +449,10 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart * @param stateId the stateId which is the associated key to the activity state * @param state the state that is associated to the activity and stateId * @param the type of the state - * @throws java.lang.IllegalStateException if vehicle.getIndex() == 0 || stateId.getIndex() < noInternalStates + * @throws java.lang.IllegalStateException if vehicle.getVehicleTypeIdentifier().getIndex() == 0 || stateId.getIndex() < noInternalStates */ public void putRouteState(VehicleRoute route, Vehicle vehicle, StateId stateId, T state) { - if (vehicle.getIndex() == 0) throw new IllegalStateException("vehicle index is 0. this should not be."); + if (vehicle.getVehicleTypeIdentifier().getIndex() == 0) throw new IllegalStateException("vehicle index is 0. this should not be."); if (stateId.getIndex() < initialNoStates) StateFactory.throwReservedIdException(stateId.toString()); putTypedInternalRouteState(route, vehicle, stateId, state); } @@ -473,13 +473,13 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart void putTypedInternalRouteState(VehicleRoute route, Vehicle vehicle, StateId stateId, T state) { if (route.isEmpty()) return; if(isIndexedBased){ - vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getIndex()][stateId.getIndex()] = state; + vehicleDependentRouteStatesArr[route.getVehicle().getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] = state; } else { if (!vehicleDependentRouteStateMap.containsKey(route)) { vehicleDependentRouteStateMap.put(route, new Object[nuVehicleTypeKeys][stateIndexCounter]); } - vehicleDependentRouteStateMap.get(route)[vehicle.getIndex()][stateId.getIndex()] = state; + vehicleDependentRouteStateMap.get(route)[vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] = state; } } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java index a5659c14..9ae37d36 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java @@ -93,7 +93,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ vehicles = vehiclesToUpdate.get(route); this.route = route; for(Vehicle v : vehicles){ - int vehicleIndex = v.getIndex(); + int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); openPickupEndTimesPerVehicle.put(vehicleIndex, new HashMap()); slackTimesPerVehicle.put(vehicleIndex, new HashMap()); actStartTimesPerVehicle.put(vehicleIndex, new HashMap()); @@ -108,10 +108,10 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ double maxTime = getMaxTimeInVehicle(activity); for(Vehicle v : vehicles) { - int vehicleIndex = v.getIndex(); + int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); Location prevActLocation = prevActLocations[vehicleIndex]; - double prevActEndTime = prevActEndTimes[v.getIndex()]; - double activityArrival = prevActEndTimes[v.getIndex()] + transportTime.getTransportTime(prevActLocation,activity.getLocation(),prevActEndTime,route.getDriver(),v); + double prevActEndTime = prevActEndTimes[v.getVehicleTypeIdentifier().getIndex()]; + double activityArrival = prevActEndTimes[v.getVehicleTypeIdentifier().getIndex()] + transportTime.getTransportTime(prevActLocation,activity.getLocation(),prevActEndTime,route.getDriver(),v); double activityStart = Math.max(activityArrival,activity.getTheoreticalEarliestOperationStartTime()); memorizeActStart(activity,v,activityStart); double activityEnd = activityStart + activityCosts.getActivityDuration(prevTourActivity, activity, activityArrival, route.getDriver(), v); @@ -145,13 +145,13 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ } private void memorizeActStart(TourActivity activity, Vehicle v, double activityStart) { - actStartTimesPerVehicle.get(v.getIndex()).put(activity, activityStart); + actStartTimesPerVehicle.get(v.getVehicleTypeIdentifier().getIndex()).put(activity, activityStart); } @Override public void finish() { for(Vehicle v : vehicles) { - int vehicleIndex = v.getIndex(); + int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); //!!! open routes !!! double routeEnd; @@ -194,7 +194,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ public void finish(List activities, Job ignore) { for (Vehicle v : vehicles) { - int vehicleIndex = v.getIndex(); + int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); //!!! open routes !!! double routeEnd; @@ -236,7 +236,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ } private double actStart(TourActivity act, Vehicle v) { - return actStartTimesPerVehicle.get(v.getIndex()).get(act); + return actStartTimesPerVehicle.get(v.getVehicleTypeIdentifier().getIndex()).get(act); } private double minSlackTime(Map openDeliveries) { diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java index e1f689e3..13165636 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java @@ -103,7 +103,11 @@ public class MaxTimeInVehicleConstraint implements HardActivityConstraint { double minSlack = Double.MAX_VALUE; if (!(nextAct instanceof End)) { - minSlack = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class); + try { + minSlack = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class); + } catch (NullPointerException npe) { + + } } double directArrTimeNextAct = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double directNextActStart = Math.max(directArrTimeNextAct, nextAct.getTheoreticalEarliestOperationStartTime()); diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java new file mode 100644 index 00000000..89955ce4 --- /dev/null +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java @@ -0,0 +1,340 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.graphhopper.jsprit.core.algorithm; +import com.graphhopper.jsprit.core.algorithm.box.Jsprit; +import com.graphhopper.jsprit.core.algorithm.state.StateId; +import com.graphhopper.jsprit.core.algorithm.state.StateManager; +import com.graphhopper.jsprit.core.algorithm.state.UpdateMaxTimeInVehicle; +import com.graphhopper.jsprit.core.problem.Location; +import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; +import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager; +import com.graphhopper.jsprit.core.problem.constraint.MaxTimeInVehicleConstraint; +import com.graphhopper.jsprit.core.problem.job.Delivery; +import com.graphhopper.jsprit.core.problem.job.Shipment; +import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl; +import com.graphhopper.jsprit.core.reporting.SolutionPrinter; +import com.graphhopper.jsprit.core.util.Solutions; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class MaxTimeInVehicleTest { + + @Test + public void testShipment(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)).setDeliveryLocation(Location.newInstance(34.781247,38.294571)) + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(20) + .build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(34.771200,32.067646)).setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(s1).build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + assertEquals(0,solution.getUnassignedJobs().size()); + assertEquals(1,solution.getRoutes().size()); + + + + } + + @Test + public void testShipmentUnassigned(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)).setDeliveryLocation(Location.newInstance(34.781247,38.294571)) + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(4) + .build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(34.771200,32.067646)).setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(s1).build(); + + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + + assertEquals(1,solution.getUnassignedJobs().size()); + assertEquals(0,solution.getRoutes().size()); + + } + + @Test + public void testDelivery(){ + + Delivery d2 = Delivery.Builder.newInstance("d2") + .setMaxTimeInVehicle(10) + .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(2,3)).setEndLocation(Location.newInstance(0,0)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(d2).build(); + + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + + assertEquals(0,solution.getUnassignedJobs().size()); + assertEquals(1,solution.getRoutes().size()); + + } + + @Test + public void testDeliveryUnassigned(){ + Delivery d2 = Delivery.Builder.newInstance("d2") + .setMaxTimeInVehicle(4) + .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(2,3)).setEndLocation(Location.newInstance(0,0)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(d2).build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + + assertEquals(1,solution.getUnassignedJobs().size()); + assertEquals(0,solution.getRoutes().size()); + + } + + @Test + public void testPickUpDropOffTwoDriversSameLocation(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)) + .setDeliveryLocation(Location.newInstance(34.781247,38.294571)) + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(10) + .build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + + VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addVehicle(v2).addJob(s1).build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + assertEquals(0,solution.getUnassignedJobs().size()); + + } + + @Test + public void testPickUpDropOffTwoDriversDiffrentLocation(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)) + .setDeliveryLocation(Location.newInstance(34.781247,38.294571)) + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(10) + .build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + + VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.5555,32.081324)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addVehicle(v2).addJob(s1).build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + + assertEquals(0,solution.getUnassignedJobs().size()); + } + + @Test + public void testRouteTwoDriversDiffrentLocationOneRoute(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(8,0)) + .setDeliveryLocation(Location.newInstance(10,0)) + .setDeliveryServiceTime(2) + .setMaxTimeInVehicle(10) + .build(); + + Delivery d2 = Delivery.Builder.newInstance("d2") + .setMaxTimeInVehicle(15) + .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setStartLocation(Location.newInstance(8,5)).setReturnToDepot(true).build(); + + VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") + .setStartLocation(Location.newInstance(5,0)).setReturnToDepot(true).build(); + + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() + .addVehicle(v1) + .addVehicle(v2) + .addJob(s1) + .addJob(d2) + .build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + assertEquals(1,solution.getRoutes().size()); + assertEquals(0,solution.getUnassignedJobs().size()); + + } + + + + @Test + public void testRouteTwoDriversTwoRouts(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(8,0)) + .setDeliveryLocation(Location.newInstance(10,0)) + .setDeliveryServiceTime(9) + .setMaxTimeInVehicle(10) + .build(); + + Delivery d2 = Delivery.Builder.newInstance("d2") + .setMaxTimeInVehicle(3) + .setLocation(Location.newInstance(10, 5)).setServiceTime(10).build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setStartLocation(Location.newInstance(8,5)).setReturnToDepot(true).build(); + + VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") + .setStartLocation(Location.newInstance(5,0)).setReturnToDepot(true).build(); + + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() + .addVehicle(v1) + .addVehicle(v2) + .addJob(s1) + .addJob(d2) + .build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + assertEquals(2,solution.getRoutes().size()); + assertEquals(0,solution.getUnassignedJobs().size()); + } + + @Test + public void testRoute(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(5,0)) + .setDeliveryLocation(Location.newInstance(10,0)) + .setMaxTimeInVehicle(5) + .build(); + + Shipment s2 = Shipment.Builder.newInstance("s2").setPickupLocation(Location.newInstance(6,5)) + .setDeliveryLocation(Location.newInstance(12,0)) + .setMaxTimeInVehicle(10) + .build(); + + Shipment s3 = Shipment.Builder.newInstance("s3").setPickupLocation(Location.newInstance(3,2)) + .setDeliveryLocation(Location.newInstance(3,5)) + .setMaxTimeInVehicle(10) + .build(); + + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setStartLocation(Location.newInstance(0,0)).setReturnToDepot(true).build(); + + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() + .addVehicle(v1) + .addJob(s1) + .addJob(s2) + .addJob(s3) + .build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + + assertEquals(1,solution.getRoutes().size()); + assertEquals(0,solution.getUnassignedJobs().size()); + } +} From b8894c327696346349894820f48e1fdb9b430d25 Mon Sep 17 00:00:00 2001 From: Iris Date: Thu, 8 Mar 2018 10:49:19 +0200 Subject: [PATCH 4/7] final changes --- .../core/problem/constraint/MaxTimeInVehicleConstraint.java | 2 +- .../graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java index 13165636..a2e67084 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java @@ -106,7 +106,7 @@ public class MaxTimeInVehicleConstraint implements HardActivityConstraint { try { minSlack = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class); } catch (NullPointerException npe) { - + //solving maxTimeInVehicle constraint } } double directArrTimeNextAct = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java index 89955ce4..63d7da65 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java @@ -220,7 +220,7 @@ public class MaxTimeInVehicleTest { .build(); Delivery d2 = Delivery.Builder.newInstance("d2") - .setMaxTimeInVehicle(15) + .setMaxTimeInVehicle(14) .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") From aaef511b75e806c3906b1900b2f5e76c6634efcc Mon Sep 17 00:00:00 2001 From: Kandel Irina Date: Sun, 11 Mar 2018 16:21:39 +0200 Subject: [PATCH 5/7] pass vehicle types --- .../state/UpdateMaxTimeInVehicle.java | 29 +- .../MaxTimeInVehicleConstraint.java | 6 +- .../core/algorithm/MaxTimeInVehicleTest.java | 286 +++++++++++++----- 3 files changed, 240 insertions(+), 81 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java index 9ae37d36..02e23300 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateMaxTimeInVehicle.java @@ -25,6 +25,7 @@ import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.solution.route.activity.*; import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; +import com.graphhopper.jsprit.core.problem.vehicle.VehicleTypeKey; import java.util.*; @@ -51,7 +52,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ private Location[] prevActLocations; - private Collection vehicles; + private Map allVehicleTypes = new HashMap<>(); private final TransportTime transportTime; @@ -80,6 +81,20 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ } + public UpdateMaxTimeInVehicle(StateManager stateManager, StateId slackTimeId, Collection vehicles, TransportTime transportTime, VehicleRoutingActivityCosts activityCosts, StateId openJobsId) { + this.stateManager = stateManager; + this.minSlackId = slackTimeId; + this.openJobsId = openJobsId; + this.transportTime = transportTime; + prevActEndTimes = new double[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1]; + prevActLocations = new Location[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1]; + this.activityCosts = activityCosts; + for (Vehicle v : vehicles) + allVehicleTypes.put(v.getVehicleTypeIdentifier(), v); + + } + + public void setVehiclesToUpdate(UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate vehiclesToUpdate) { this.vehiclesToUpdate = vehiclesToUpdate; } @@ -90,9 +105,9 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ openPickupEndTimesPerVehicle.clear(); slackTimesPerVehicle.clear(); actStartTimesPerVehicle.clear(); - vehicles = vehiclesToUpdate.get(route); + allVehicleTypes.put(route.getVehicle().getVehicleTypeIdentifier(), route.getVehicle()); this.route = route; - for(Vehicle v : vehicles){ + for(Vehicle v : allVehicleTypes.values()){ int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); openPickupEndTimesPerVehicle.put(vehicleIndex, new HashMap()); slackTimesPerVehicle.put(vehicleIndex, new HashMap()); @@ -107,7 +122,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ public void visit(TourActivity activity) { double maxTime = getMaxTimeInVehicle(activity); - for(Vehicle v : vehicles) { + for(Vehicle v : allVehicleTypes.values()) { int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); Location prevActLocation = prevActLocations[vehicleIndex]; double prevActEndTime = prevActEndTimes[v.getVehicleTypeIdentifier().getIndex()]; @@ -150,7 +165,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ @Override public void finish() { - for(Vehicle v : vehicles) { + for(Vehicle v : allVehicleTypes.values()) { int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); //!!! open routes !!! @@ -193,7 +208,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ } public void finish(List activities, Job ignore) { - for (Vehicle v : vehicles) { + for (Vehicle v : allVehicleTypes.values()) { int vehicleIndex = v.getVehicleTypeIdentifier().getIndex(); //!!! open routes !!! @@ -242,7 +257,7 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{ private double minSlackTime(Map openDeliveries) { double min = Double.MAX_VALUE; for(Double value : openDeliveries.values()){ - if(value < min) min = value; + if(value < min) min = value; } return min; } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java index a2e67084..e1f689e3 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java @@ -103,11 +103,7 @@ public class MaxTimeInVehicleConstraint implements HardActivityConstraint { double minSlack = Double.MAX_VALUE; if (!(nextAct instanceof End)) { - try { - minSlack = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class); - } catch (NullPointerException npe) { - //solving maxTimeInVehicle constraint - } + minSlack = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class); } double directArrTimeNextAct = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double directNextActStart = Math.max(directArrTimeNextAct, nextAct.getTheoreticalEarliestOperationStartTime()); diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java index 63d7da65..f70df159 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java @@ -25,24 +25,37 @@ import com.graphhopper.jsprit.core.problem.Location; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager; import com.graphhopper.jsprit.core.problem.constraint.MaxTimeInVehicleConstraint; +import com.graphhopper.jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import com.graphhopper.jsprit.core.problem.driver.Driver; import com.graphhopper.jsprit.core.problem.job.Delivery; import com.graphhopper.jsprit.core.problem.job.Shipment; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; +import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow; +import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; +import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl; +import com.graphhopper.jsprit.core.problem.vehicle.VehicleTypeImpl; import com.graphhopper.jsprit.core.reporting.SolutionPrinter; import com.graphhopper.jsprit.core.util.Solutions; import org.junit.Test; +import java.util.Iterator; +import java.util.Random; +import java.util.UUID; + import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class MaxTimeInVehicleTest { @Test public void testShipment(){ Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)).setDeliveryLocation(Location.newInstance(34.781247,38.294571)) - .setDeliveryServiceTime(10) - .setMaxTimeInVehicle(20) - .build(); + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(20) + .build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(34.771200,32.067646)).setEndLocation(Location.newInstance(34.768404,32.081525)).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(s1).build(); @@ -50,7 +63,7 @@ public class MaxTimeInVehicleTest { StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -68,9 +81,9 @@ public class MaxTimeInVehicleTest { @Test public void testShipmentUnassigned(){ Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)).setDeliveryLocation(Location.newInstance(34.781247,38.294571)) - .setDeliveryServiceTime(10) - .setMaxTimeInVehicle(4) - .build(); + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(4) + .build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(34.771200,32.067646)).setEndLocation(Location.newInstance(34.768404,32.081525)).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(s1).build(); @@ -79,7 +92,7 @@ public class MaxTimeInVehicleTest { StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -97,8 +110,8 @@ public class MaxTimeInVehicleTest { public void testDelivery(){ Delivery d2 = Delivery.Builder.newInstance("d2") - .setMaxTimeInVehicle(10) - .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); + .setMaxTimeInVehicle(10) + .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(2,3)).setEndLocation(Location.newInstance(0,0)).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(d2).build(); @@ -107,7 +120,7 @@ public class MaxTimeInVehicleTest { StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -124,8 +137,8 @@ public class MaxTimeInVehicleTest { @Test public void testDeliveryUnassigned(){ Delivery d2 = Delivery.Builder.newInstance("d2") - .setMaxTimeInVehicle(4) - .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); + .setMaxTimeInVehicle(4) + .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(2,3)).setEndLocation(Location.newInstance(0,0)).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addJob(d2).build(); @@ -133,7 +146,7 @@ public class MaxTimeInVehicleTest { StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -150,24 +163,24 @@ public class MaxTimeInVehicleTest { @Test public void testPickUpDropOffTwoDriversSameLocation(){ Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)) - .setDeliveryLocation(Location.newInstance(34.781247,38.294571)) - .setDeliveryServiceTime(10) - .setMaxTimeInVehicle(10) - .build(); + .setDeliveryLocation(Location.newInstance(34.781247,38.294571)) + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(10) + .build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") - .setStartLocation(Location.newInstance(34.771200,32.067646)) - .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") - .setStartLocation(Location.newInstance(34.771200,32.067646)) - .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addVehicle(v2).addJob(s1).build(); StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -182,24 +195,24 @@ public class MaxTimeInVehicleTest { @Test public void testPickUpDropOffTwoDriversDiffrentLocation(){ Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)) - .setDeliveryLocation(Location.newInstance(34.781247,38.294571)) - .setDeliveryServiceTime(10) - .setMaxTimeInVehicle(10) - .build(); + .setDeliveryLocation(Location.newInstance(34.781247,38.294571)) + .setDeliveryServiceTime(10) + .setMaxTimeInVehicle(10) + .build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") - .setStartLocation(Location.newInstance(34.771200,32.067646)) - .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.768404,32.081525)).build(); VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") - .setStartLocation(Location.newInstance(34.771200,32.067646)) - .setEndLocation(Location.newInstance(34.5555,32.081324)).build(); + .setStartLocation(Location.newInstance(34.771200,32.067646)) + .setEndLocation(Location.newInstance(34.5555,32.081324)).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v1).addVehicle(v2).addJob(s1).build(); StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -239,7 +252,7 @@ public class MaxTimeInVehicleTest { StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -257,32 +270,32 @@ public class MaxTimeInVehicleTest { @Test public void testRouteTwoDriversTwoRouts(){ Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(8,0)) - .setDeliveryLocation(Location.newInstance(10,0)) - .setDeliveryServiceTime(9) - .setMaxTimeInVehicle(10) - .build(); + .setDeliveryLocation(Location.newInstance(10,0)) + .setDeliveryServiceTime(9) + .setMaxTimeInVehicle(10) + .build(); Delivery d2 = Delivery.Builder.newInstance("d2") - .setMaxTimeInVehicle(3) - .setLocation(Location.newInstance(10, 5)).setServiceTime(10).build(); + .setMaxTimeInVehicle(3) + .setLocation(Location.newInstance(10, 5)).setServiceTime(10).build(); VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") - .setStartLocation(Location.newInstance(8,5)).setReturnToDepot(true).build(); + .setStartLocation(Location.newInstance(8,5)).setReturnToDepot(true).build(); VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") - .setStartLocation(Location.newInstance(5,0)).setReturnToDepot(true).build(); + .setStartLocation(Location.newInstance(5,0)).setReturnToDepot(true).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() - .addVehicle(v1) - .addVehicle(v2) - .addJob(s1) - .addJob(d2) - .build(); + .addVehicle(v1) + .addVehicle(v2) + .addJob(s1) + .addJob(d2) + .build(); StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); @@ -294,38 +307,173 @@ public class MaxTimeInVehicleTest { assertEquals(0,solution.getUnassignedJobs().size()); } + Random RANDOM = new Random(); + @Test - public void testRoute(){ - Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(5,0)) - .setDeliveryLocation(Location.newInstance(10,0)) - .setMaxTimeInVehicle(5) - .build(); + public void testRouteTwoDriversTwoRouts_NotAllAssigned() { + int numJobs = Math.abs(RANDOM.nextInt(100)) + 10, + start = Math.abs(RANDOM.nextInt(100)), + maxTimeInVehicle = 50 + Math.abs(RANDOM.nextInt(50)), + serviceTime = Math.abs(RANDOM.nextInt(10)) + 5, + end = start + numJobs * maxTimeInVehicle + numJobs * serviceTime + Math.abs(RANDOM.nextInt(200)); - Shipment s2 = Shipment.Builder.newInstance("s2").setPickupLocation(Location.newInstance(6,5)) - .setDeliveryLocation(Location.newInstance(12,0)) - .setMaxTimeInVehicle(10) - .build(); + final VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + for (int i = 0; i < 5; ++i) { + builder.addVehicle(VehicleImpl.Builder.newInstance(UUID.randomUUID().toString()) + .setStartLocation(Location.newInstance(8, 5)).setReturnToDepot(true) + .setEarliestStart(start).setLatestArrival(end) + .setType(VehicleTypeImpl.Builder.newInstance(UUID.randomUUID().toString()).addCapacityDimension(0, numJobs).setCostPerDistance(1).setFixedCost(100).build()) + .build()); + } - Shipment s3 = Shipment.Builder.newInstance("s3").setPickupLocation(Location.newInstance(3,2)) - .setDeliveryLocation(Location.newInstance(3,5)) - .setMaxTimeInVehicle(10) - .build(); + for (int i = 0; i < numJobs; ++i) { + builder.addJob(Delivery.Builder.newInstance("d" + i) + .setMaxTimeInVehicle(maxTimeInVehicle) + .addTimeWindow(TimeWindow.newInstance(start, end)) + .addSizeDimension(0, 1) + .setLocation(Location.newInstance(RANDOM.nextDouble(), RANDOM.nextDouble())).setServiceTime(serviceTime).build()); + } + + VehicleRoutingProblemSolution solution = getVehicleRoutingProblemSolution(builder); + + assertFalse(solution.getRoutes().isEmpty()); + final Iterator iterator = solution.getRoutes().iterator(); + while (iterator.hasNext()) { + final VehicleRoute route = iterator.next(); + final TourActivity lastActivity = route.getActivities().get(route.getActivities().size() - 1); + assertTrue(lastActivity.getArrTime() - route.getStart().getEndTime() <= maxTimeInVehicle); + } + } + + @Test + public void testRouteTwoDriversTwoRoutsAllAssignedToCheapestDrivers() { + int numJobs = 100, + start = 0, + maxTimeInVehicle = 50, + serviceTime = 4, + end = 360; + + //in route 50/(4+1)=10 tasks + + final VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + final VehicleTypeImpl cheap = VehicleTypeImpl.Builder.newInstance(UUID.randomUUID().toString()).addCapacityDimension(0, numJobs).setCostPerDistance(1).setFixedCost(10).build(); + for (int i = 0; i < 10; ++i) { + builder.addVehicle(VehicleImpl.Builder.newInstance(UUID.randomUUID().toString()) + .setStartLocation(Location.newInstance(8, 5)).setReturnToDepot(true) + .setEarliestStart(start).setLatestArrival(end) + .setType(cheap) + .build()); + } - VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") - .setStartLocation(Location.newInstance(0,0)).setReturnToDepot(true).build(); + final VehicleTypeImpl expensive = VehicleTypeImpl.Builder.newInstance(UUID.randomUUID().toString()).addCapacityDimension(0, numJobs).setCostPerDistance(1).setFixedCost(100).build(); + for (int i = 0; i < 10; ++i) { + builder.addVehicle(VehicleImpl.Builder.newInstance(UUID.randomUUID().toString()) + .setStartLocation(Location.newInstance(8, 5)).setReturnToDepot(true) + .setEarliestStart(start).setLatestArrival(end) + .setType(expensive) + .build()); + } - VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() - .addVehicle(v1) - .addJob(s1) - .addJob(s2) - .addJob(s3) - .build(); + for (int i = 0; i < numJobs; ++i) { + builder.addJob(Delivery.Builder.newInstance("d" + i) + .setMaxTimeInVehicle(maxTimeInVehicle) + .addTimeWindow(TimeWindow.newInstance(start, end)) + .addSizeDimension(0, 1) + .setLocation(Location.newInstance(RANDOM.nextDouble(), RANDOM.nextDouble())).setServiceTime(serviceTime).build()); + } + + VehicleRoutingProblemSolution solution = getVehicleRoutingProblemSolution(builder); + + final Iterator iterator = solution.getRoutes().iterator(); + while (iterator.hasNext()) { + final VehicleRoute route = iterator.next(); + final TourActivity lastActivity = route.getActivities().get(route.getActivities().size() - 1); + assertTrue(lastActivity.getArrTime() - route.getStart().getEndTime() <= maxTimeInVehicle); + assertEquals(route.getVehicle().getType(), cheap); + } + + assertTrue(solution.getUnassignedJobs().isEmpty()); + } + + private VehicleRoutingProblemSolution getVehicleRoutingProblemSolution(VehicleRoutingProblem.Builder builder) { + VehicleRoutingProblem vrp = builder + .setRoutingCost(new VehicleRoutingTransportCosts() { + @Override + public double getBackwardTransportCost(Location location, Location location1, double v, Driver driver, Vehicle vehicle) { + return 1; + } + + @Override + public double getBackwardTransportTime(Location location, Location location1, double v, Driver driver, Vehicle vehicle) { + return 1; + } + + @Override + public double getTransportCost(Location location, Location location1, double v, Driver driver, Vehicle vehicle) { + return 1; + } + + @Override + public double getTransportTime(Location location, Location location1, double v, Driver driver, Vehicle vehicle) { + return 1; + } + + @Override + public double getDistance(Location location, Location location1, double v, Vehicle vehicle) { + return 1; + } + }) + .setFleetSize(VehicleRoutingProblem.FleetSize.FINITE) + .build(); StateManager stateManager = new StateManager(vrp); StateId id = stateManager.createStateId("max-time"); StateId openJobsId = stateManager.createStateId("open-jobs-id"); - stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); + + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); + + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + vra.setMaxIterations(100); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); + return solution; + } + + @Test + public void testRoute(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(5,0)) + .setDeliveryLocation(Location.newInstance(10,0)) + .setMaxTimeInVehicle(5) + .build(); + + Shipment s2 = Shipment.Builder.newInstance("s2").setPickupLocation(Location.newInstance(6,5)) + .setDeliveryLocation(Location.newInstance(12,0)) + .setMaxTimeInVehicle(10) + .build(); + + Shipment s3 = Shipment.Builder.newInstance("s3").setPickupLocation(Location.newInstance(3,2)) + .setDeliveryLocation(Location.newInstance(3,5)) + .setMaxTimeInVehicle(10) + .build(); + + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setStartLocation(Location.newInstance(0,0)).setReturnToDepot(true).build(); + + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() + .addVehicle(v1) + .addJob(s1) + .addJob(s2) + .addJob(s3) + .build(); + + StateManager stateManager = new StateManager(vrp); + StateId id = stateManager.createStateId("max-time"); + StateId openJobsId = stateManager.createStateId("open-jobs-id"); + stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getVehicles(), vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId)); ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); From dc8adca385406fd36c45f591f99b6bb1788ebbbe Mon Sep 17 00:00:00 2001 From: Kandel Irina Date: Mon, 12 Mar 2018 08:35:04 +0200 Subject: [PATCH 6/7] fixes --- .../MaxTimeInVehicleConstraint.java | 15 +++--- .../core/algorithm/MaxTimeInVehicleTest.java | 52 ++++++++++++++----- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java index e1f689e3..bc463474 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/MaxTimeInVehicleConstraint.java @@ -26,10 +26,7 @@ import com.graphhopper.jsprit.core.problem.cost.VehicleRoutingActivityCosts; import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.job.Shipment; import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext; -import com.graphhopper.jsprit.core.problem.solution.route.activity.DeliveryActivity; -import com.graphhopper.jsprit.core.problem.solution.route.activity.End; -import com.graphhopper.jsprit.core.problem.solution.route.activity.PickupActivity; -import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; +import com.graphhopper.jsprit.core.problem.solution.route.activity.*; import java.util.Collections; import java.util.Map; @@ -74,7 +71,10 @@ public class MaxTimeInVehicleConstraint implements HardActivityConstraint { double newActStart = Math.max(newActArrival, newAct.getTheoreticalEarliestOperationStartTime()); double newActDeparture = newActStart + activityCosts.getActivityDuration(prevAct, newAct, newActArrival, iFacts.getNewDriver(), iFacts.getNewVehicle()); double nextActArrival = newActDeparture + transportTime.getTransportTime(newAct.getLocation(),nextAct.getLocation(),newActDeparture,iFacts.getNewDriver(),iFacts.getNewVehicle()); - double nextActStart = Math.max(nextActArrival,nextAct.getTheoreticalEarliestOperationStartTime()); + double nextActStart = Math.max(nextActArrival, nextAct.getTheoreticalEarliestOperationStartTime()); + if (nextAct instanceof DeliverService && nextActStart - iFacts.getNewVehicle().getEarliestDeparture() > ((TourActivity.JobActivity)nextAct).getJob().getMaxTimeInVehicle()) { + return ConstraintsStatus.NOT_FULFILLED; + } if(newAct instanceof DeliveryActivity){ double pickupEnd; if(iFacts.getAssociatedActivities().size() == 1){ @@ -107,10 +107,9 @@ public class MaxTimeInVehicleConstraint implements HardActivityConstraint { } double directArrTimeNextAct = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double directNextActStart = Math.max(directArrTimeNextAct, nextAct.getTheoreticalEarliestOperationStartTime()); - double additionalTimeOfNewAct = (nextActStart - prevActDepTime) - (directNextActStart - prevActDepTime); + double additionalTimeOfNewAct = nextActStart - directNextActStart; if (additionalTimeOfNewAct > minSlack) { - if (newActIsPickup) return ConstraintsStatus.NOT_FULFILLED; - else return ConstraintsStatus.NOT_FULFILLED; + return ConstraintsStatus.NOT_FULFILLED; } if (newActIsDelivery) { Map openJobsAtNext; diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java index f70df159..9e5134fc 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/MaxTimeInVehicleTest.java @@ -50,6 +50,8 @@ import static org.junit.Assert.assertTrue; public class MaxTimeInVehicleTest { + Random RANDOM = new Random(); + @Test public void testShipment(){ Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(34.773586,32.079754)).setDeliveryLocation(Location.newInstance(34.781247,38.294571)) @@ -73,9 +75,6 @@ public class MaxTimeInVehicleTest { SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); assertEquals(0,solution.getUnassignedJobs().size()); assertEquals(1,solution.getRoutes().size()); - - - } @Test @@ -307,8 +306,6 @@ public class MaxTimeInVehicleTest { assertEquals(0,solution.getUnassignedJobs().size()); } - Random RANDOM = new Random(); - @Test public void testRouteTwoDriversTwoRouts_NotAllAssigned() { int numJobs = Math.abs(RANDOM.nextInt(100)) + 10, @@ -334,7 +331,7 @@ public class MaxTimeInVehicleTest { .setLocation(Location.newInstance(RANDOM.nextDouble(), RANDOM.nextDouble())).setServiceTime(serviceTime).build()); } - VehicleRoutingProblemSolution solution = getVehicleRoutingProblemSolution(builder); + VehicleRoutingProblemSolution solution = getVehicleRoutingProblemSolution(builder, true, 4); assertFalse(solution.getRoutes().isEmpty()); final Iterator iterator = solution.getRoutes().iterator(); @@ -383,7 +380,7 @@ public class MaxTimeInVehicleTest { .setLocation(Location.newInstance(RANDOM.nextDouble(), RANDOM.nextDouble())).setServiceTime(serviceTime).build()); } - VehicleRoutingProblemSolution solution = getVehicleRoutingProblemSolution(builder); + VehicleRoutingProblemSolution solution = getVehicleRoutingProblemSolution(builder, true, 4); final Iterator iterator = solution.getRoutes().iterator(); while (iterator.hasNext()) { @@ -396,9 +393,38 @@ public class MaxTimeInVehicleTest { assertTrue(solution.getUnassignedJobs().isEmpty()); } - private VehicleRoutingProblemSolution getVehicleRoutingProblemSolution(VehicleRoutingProblem.Builder builder) { - VehicleRoutingProblem vrp = builder - .setRoutingCost(new VehicleRoutingTransportCosts() { + @Test + public void testLowMaxTimeCauseTwoRoutes(){ + Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(8,0)) + .setDeliveryLocation(Location.newInstance(10,0)) + .setDeliveryServiceTime(2) + .setMaxTimeInVehicle(10) + .build(); + + Delivery d2 = Delivery.Builder.newInstance("d2") + .setMaxTimeInVehicle(13) + .setLocation(Location.newInstance(10, 5)).setServiceTime(2).build(); + + VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1") + .setStartLocation(Location.newInstance(8,5)).setReturnToDepot(true).build(); + + VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2") + .setStartLocation(Location.newInstance(5,0)).setReturnToDepot(true).build(); + + + final VehicleRoutingProblemSolution solution = getVehicleRoutingProblemSolution(VehicleRoutingProblem.Builder.newInstance() + .addVehicle(v1) + .addVehicle(v2) + .addJob(s1) + .addJob(d2), false, 4); + assertEquals(2, solution.getRoutes().size()); + assertEquals(0, solution.getUnassignedJobs().size()); + + } + + private VehicleRoutingProblemSolution getVehicleRoutingProblemSolution(VehicleRoutingProblem.Builder builder, boolean routeCost, int numThreads) { + if (routeCost) { + builder.setRoutingCost(new VehicleRoutingTransportCosts() { @Override public double getBackwardTransportCost(Location location, Location location1, double v, Driver driver, Vehicle vehicle) { return 1; @@ -423,7 +449,9 @@ public class MaxTimeInVehicleTest { public double getDistance(Location location, Location location1, double v, Vehicle vehicle) { return 1; } - }) + }); + } + VehicleRoutingProblem vrp = builder .setFleetSize(VehicleRoutingProblem.FleetSize.FINITE) .build(); @@ -435,7 +463,7 @@ public class MaxTimeInVehicleTest { ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL); - VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm(); + VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager,constraintManager).setProperty(Jsprit.Parameter.THREADS, String.valueOf(numThreads)).buildAlgorithm(); vra.setMaxIterations(100); VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE); From e1e002131ea53c207e6eb620f796b16ca94ec0d8 Mon Sep 17 00:00:00 2001 From: Kandel Irina Date: Mon, 12 Mar 2018 09:17:38 +0200 Subject: [PATCH 7/7] ?! --- .../graphhopper/jsprit/core/algorithm/state/StateManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java index 05eaa321..9d9fbb63 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/StateManager.java @@ -449,10 +449,10 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart * @param stateId the stateId which is the associated key to the activity state * @param state the state that is associated to the activity and stateId * @param the type of the state - * @throws java.lang.IllegalStateException if vehicle.getVehicleTypeIdentifier().getIndex() == 0 || stateId.getIndex() < noInternalStates + * @throws java.lang.IllegalStateException if vehicle.getIndex() == 0 || stateId.getIndex() < noInternalStates */ public void putRouteState(VehicleRoute route, Vehicle vehicle, StateId stateId, T state) { - if (vehicle.getVehicleTypeIdentifier().getIndex() == 0) throw new IllegalStateException("vehicle index is 0. this should not be."); + if (vehicle.getIndex() == 0) throw new IllegalStateException("vehicle index is 0. this should not be."); if (stateId.getIndex() < initialNoStates) StateFactory.throwReservedIdException(stateId.toString()); putTypedInternalRouteState(route, vehicle, stateId, state); }