2626import com .graphhopper .jsprit .core .problem .solution .route .activity .TourActivity ;
2727import com .graphhopper .jsprit .core .problem .vehicle .Vehicle ;
2828
29- import java .util .Arrays ;
3029import java .util .Collection ;
30+ import java .util .Collections ;
3131import java .util .Iterator ;
3232
3333public 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