Fix issue #4133: Correct negative transit handling in FinalizeAllowedVehicles #4868
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes a regression introduced in v9.9 (commit 847cfc9) where
FinalizeAllowedVehicles()
incorrectly excluded vehicles from nodes with negative unary transits, causing heterogeneous VRP problems with reload/load-tracking dimensions to produce suboptimal solutions with excessive dropped stops.The Bug
The optimization in
FinalizeAllowedVehicles()
checked:This is incorrect for negative transits. A vehicle with
capacity=50000
was excluded from nodes withtransit=-70000
, even whenslack_max=140000
was sufficient to absorb the negative transit.Why PR #4853 Was Incorrect
The previous fix attempted to skip all negative transits:
As @lperron correctly noted, this breaks feasibility guarantees. A negative transit with
abs(transit) > slack_max
should genuinely exclude vehicles, but that fix allowed them through.The Correct Fix
Negative transits are feasible when the vehicle can absorb them via combined capacity and slack:
This translates to:
transit ≤ capacity
(must fit in vehicle)abs(transit) ≤ capacity + slack_max
(absorbed via capacity headroom + slack)This is mathematically correct: a vehicle starting with
cumul = capacity
can decrease by up tocapacity + slack_max
before violating the lower bound (0).Regression Test
A regression test reproducing the exact bug is available: test_issue_4133_regression.py
Results with this fix:
Expected results on v9.9-9.14 (broken versions):
Impact
Fixes routing problems affected for 20+ months (v9.9.3963 through v9.14.6206):
Fixes #4133