Hi,
In the min-waiting-time case,
LocalActivityInsertionCostsCalculator, the impact of the insertion of the new activity on the whole route (subsequent activities) is calculated as waitingTime_savings. In this way, the calculation of the global impact does not require visiting each of the subsequent activities and thus it saves computational time.
Two reasons for it to work: 1) the penalty on the waiting time is linear, i.e., waitingTime_savings = waitingTime_savings_timeUnit * iFacts.getRoute().getVehicle().getType().getVehicleCostParams().perWaitingTimeUnit; 2) the nature of waiting time, as Stefan stated in
this post: "the end time delay can be used to reduce waiting time somewhere in the route. However, this reduction cannot be bigger than the existing futureWaiting time, i.e. the sum of waiting times at subsequent customers", i.e., waitingTime_savings_timeUnit = Math.min(futureWaiting, endTimeDelay_nextAct).
When I try to follow the same logic for the soft time windows constraint, I would need three states similar to FUTURE_WAITING: 1) totalActivityEarly: sum of times of being early at subsequent activities (i.e., the same as FUTURE_WAITING); 2) totalActivityLate: sum of times of being late at subsequent activities; and 3) routeLate: time of being late for vehicle end time.
The time unit savings in totalActivityEarly and increases in routeLate as a result of the insertion of the new activity can be calculated in the same way as for waiting time: Math.min(totalActivityEarly, endTimeDelay_nextAct) for the former, and Math.max(0, endTimeDelay_nextAct - totalActivityEarly) for the latter.
However, for the time unit increases in totalActivityLate, it is more complicated: it requires visiting each of the subsequent activities. For example, suppose there are subsequent activities 1, 2, 3, ..., N, totalActivityEarly = 15 minutes, totalActivityLate = 0, routeLate = 0 and endTimeDelay_nextAct = 10 minutes. For the sake of simplification, assume operation time is 0 for all activities. Then consider two scenarios: 1) before insertion, the vehicle is early only for activity 1 and arrives exactly on time for all others. So after the insertion, the 10 minute endTimeDelay_nextAct is absorbed by the times of being early at activity 1 and it will not affect the arrival time at any of other subsequent activities, thus totalActivityEarly = 5 minutes, totalActivityLate = 0, routeLate = 0. 2) before insertion, the vehicle is early only for activity N and arrives exactly on time for all others. So after the insertion, the 10 minute endTimeDelay_nextAct will cause the vehicle being late for all subsequent activities except activity N, thus totalActivityEarly = 5 minutes, totalActivityLate = 10 * (N - 1) minutes, routeLate = 0.
In summary, the same method cannot be applied to the soft time windows case. The calculation of the time unit increases in totalActivityLate requires visiting each of the subsequent activities, which will increase the computational time significantly. Is there a way to get around this?
Moreover, I would like to use a non-linear penalty function for the time window violation, because in the case of multiple activities being late, I would like the one with an earlier end time to be visited first. In this case, even for totalActivityEarly and routeLate, it requires visiting each of the subsequent activities as the cost function is not additive.
Hopefully the above is understandable.
Please let me know what you think. Thanks.
Best regards,
He