Skip to content

Commit 47428eb

Browse files
committed
make sure vehicle switch is feasible
1 parent 90ca2e5 commit 47428eb

File tree

1 file changed

+53
-16
lines changed

1 file changed

+53
-16
lines changed

jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/state/UpdateVehicleDependentPracticalTimeWindows.java

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity;
2727
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
2828

29-
import java.util.Arrays;
3029
import java.util.Collection;
30+
import java.util.Collections;
3131
import java.util.Iterator;
3232

3333
public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor, StateUpdater {
@@ -40,6 +40,12 @@ public void visit(VehicleRoute route) {
4040
visit(revIterator.next());
4141
}
4242
finish();
43+
44+
Iterator<TourActivity> tourIterator = route.getTourActivities().iterator();
45+
while (tourIterator.hasNext()) {
46+
visitForward(tourIterator.next());
47+
}
48+
finishForward();
4349
}
4450

4551
public interface VehiclesToUpdate {
@@ -48,7 +54,7 @@ public interface VehiclesToUpdate {
4854

4955
}
5056

51-
private VehiclesToUpdate vehiclesToUpdate = route -> Arrays.asList(route.getVehicle());
57+
private VehiclesToUpdate vehiclesToUpdate = route -> Collections.singletonList(route.getVehicle());
5258

5359
private final StateManager stateManager;
5460

@@ -58,9 +64,13 @@ public interface VehiclesToUpdate {
5864

5965
private VehicleRoute route;
6066

61-
private double[] latest_arrTimes_at_prevAct;
67+
private final double[] vehicleDependentLatestArrTimesPrevAct;
68+
69+
private final double[] vehicleDependentEarliestDepartureTimesPrevAct;
70+
71+
private final Location[] vehicleDependentLocationPrevActBackward;
6272

63-
private Location[] location_of_prevAct;
73+
private final Location[] vehicleDependentLocationPrevActForward;
6474

6575
private Collection<Vehicle> vehicles;
6676

@@ -69,47 +79,74 @@ public UpdateVehicleDependentPracticalTimeWindows(StateManager stateManager, Veh
6979
this.stateManager = stateManager;
7080
this.transportCosts = tpCosts;
7181
this.activityCosts = activityCosts;
72-
latest_arrTimes_at_prevAct = new double[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1];
73-
location_of_prevAct = new Location[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1];
82+
vehicleDependentLatestArrTimesPrevAct = new double[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1];
83+
vehicleDependentEarliestDepartureTimesPrevAct = new double[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1];
84+
vehicleDependentLocationPrevActBackward = new Location[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1];
85+
vehicleDependentLocationPrevActForward = new Location[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1];
7486
}
7587

7688
public void setVehiclesToUpdate(VehiclesToUpdate vehiclesToUpdate) {
7789
this.vehiclesToUpdate = vehiclesToUpdate;
7890
}
7991

8092

81-
public void begin(VehicleRoute route) {
93+
void begin(VehicleRoute route) {
8294
this.route = route;
8395
vehicles = vehiclesToUpdate.get(route);
8496
for (Vehicle vehicle : vehicles) {
85-
latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = vehicle.getLatestArrival();
97+
vehicleDependentLatestArrTimesPrevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = vehicle.getLatestArrival();
98+
vehicleDependentEarliestDepartureTimesPrevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = vehicle.getEarliestDeparture();
8699
Location location = vehicle.getEndLocation();
87100
if(!vehicle.isReturnToDepot()){
88101
location = route.getEnd().getLocation();
89102
}
90-
location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = location;
103+
vehicleDependentLocationPrevActBackward[vehicle.getVehicleTypeIdentifier().getIndex()] = location;
104+
Location startLocation = vehicle.getStartLocation();
105+
if (vehicle.getStartLocation() == null) {
106+
startLocation = route.getStart().getLocation();
107+
}
108+
vehicleDependentLocationPrevActForward[vehicle.getVehicleTypeIdentifier().getIndex()] = startLocation;
91109
}
92110
}
93111

94112

95-
public void visit(TourActivity activity) {
113+
void visit(TourActivity activity) {
96114
for (Vehicle vehicle : vehicles) {
97-
double latestArrTimeAtPrevAct = latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()];
98-
Location prevLocation = location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()];
115+
double latestArrTimeAtPrevAct = vehicleDependentLatestArrTimesPrevAct[vehicle.getVehicleTypeIdentifier().getIndex()];
116+
Location prevLocation = vehicleDependentLocationPrevActBackward[vehicle.getVehicleTypeIdentifier().getIndex()];
99117
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevLocation,
100-
latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activityCosts.getActivityDuration(activity, latestArrTimeAtPrevAct, route.getDriver(), route.getVehicle());
118+
latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activityCosts.getActivityDuration(activity, latestArrTimeAtPrevAct, route.getDriver(), vehicle);
101119
double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
102120
if (latestArrivalTime < activity.getTheoreticalEarliestOperationStartTime()) {
103121
stateManager.putTypedInternalRouteState(route, vehicle, InternalStates.SWITCH_NOT_FEASIBLE, true);
104122
}
105123
stateManager.putInternalTypedActivityState(activity, vehicle, InternalStates.LATEST_OPERATION_START_TIME, latestArrivalTime);
106-
latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = latestArrivalTime;
107-
location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = activity.getLocation();
124+
vehicleDependentLatestArrTimesPrevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = latestArrivalTime;
125+
vehicleDependentLocationPrevActBackward[vehicle.getVehicleTypeIdentifier().getIndex()] = activity.getLocation();
126+
127+
}
128+
}
129+
130+
void visitForward(TourActivity activity) {
131+
for (Vehicle vehicle : vehicles) {
132+
double earliestDepartureAtPrevAct = vehicleDependentEarliestDepartureTimesPrevAct[vehicle.getVehicleTypeIdentifier().getIndex()];
133+
Location earliestLocation = vehicleDependentLocationPrevActForward[vehicle.getVehicleTypeIdentifier().getIndex()];
134+
double potentialEarliestArrivalTimeAtCurrAct = earliestDepartureAtPrevAct + transportCosts.getTransportTime(earliestLocation, activity.getLocation(), earliestDepartureAtPrevAct, route.getDriver(), vehicle);
135+
if (potentialEarliestArrivalTimeAtCurrAct > activity.getTheoreticalLatestOperationStartTime()) {
136+
stateManager.putTypedInternalRouteState(route, vehicle, InternalStates.SWITCH_NOT_FEASIBLE, true);
137+
}
138+
double earliestStart = Math.max(potentialEarliestArrivalTimeAtCurrAct, activity.getTheoreticalEarliestOperationStartTime());
139+
double earliestDeparture = earliestStart + activityCosts.getActivityDuration(activity, earliestStart, route.getDriver(), vehicle);
140+
vehicleDependentEarliestDepartureTimesPrevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = earliestDeparture;
141+
vehicleDependentLocationPrevActForward[vehicle.getVehicleTypeIdentifier().getIndex()] = activity.getLocation();
108142
}
109143
}
110144

111145

112-
public void finish() {
146+
void finish() {
147+
}
148+
149+
void finishForward() {
113150
}
114151

115152
}

0 commit comments

Comments
 (0)