Multiple critical bugs in 3-opt search #1
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.
I think I stumbled upon several bugs in the VRPH ThreeOpt.cpp.
Firstly, assume that the route nodes are indexed n0-n1-n2-... the original implementation started from edges n0-n1 n2-n3 n4-n5, which caused the edges n1-n2 n3-n4 etc. not to be checked. The same bug was also in the O(n^3) main search loop, where the edges between consecutive nodes were similarly skipped.
Also, the end nodes for the loop were incorrect (too many lookups from the prev_array) as the search was terminated before reaching the final nodes of the route. As an result 3-opt did not work as expected and produced wrong (or severely wrong, depending on the input) results.
There was an additional issue. the route[r].end was not updated by every type of the ThreeOpt::move. Therefore, it was possible that a move was accepted and the subsequent 3-opt searches terminated early (to the node that was previously the route end node).
I have verified that the fixed 3opt procedure produces identical results to my independent 3-opt implementation written in python for a 7 point synthetic problem with 100 random initial solutions of 1,2 and 3 routes each. The non-patched version produces inferior solutions.
Smoke test of the metaheuristics (ej,init,rtr,sa) on the test_instance.vrp seems to indicate nothing has broken due to the patch. For some reason there is little to none impact on the quality of the metaheuristic solutions. Only if only 3-opt is forced for rtr, after the fix it produces slightly better solutions. Perhaps the other local search operators have made up for the dysfunctional 3-opt?