Uh oh!
There was an error while loading. Please reload this page.
feat: implement bidirectional Dijkstra - #789
Open
ChrisJr404 wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
This adds a bidirectional variant of Dijkstra's algorithm,
dijkstra_bidirectional, continuing the work started withbfs_bidirectional(#543 asks for BFS, Dijkstra and A*; BFS landed in v4.14.0, this is the Dijkstra half).What it does
Two searches run at the same time: one forward from
startfollowingsuccessors, and one backward fromendfollowingpredecessors, each advancing in order of increasing cost. The search stops as soon as a node has been settled by both frontiers, at which point the cheapest complete path discovered so far is optimal. On graphs where the frontier grows quickly with distance this settles far fewer nodes than a single-directional search, since two small frontiers are usually cheaper to grow than one large one.The signature mirrors the rest of the
dijkstrafamily (single&Nstart,FnMut(&N) -> IntoIterator<Item = (N, C)>), with an extrapredecessorsclosure so directed graphs are supported. For undirected graphs the same closure can be passed for both, exactly likebfs_bidirectional. Internally it reuses the module's existingSmallestHolderheap entry and theFxIndexMapparent-pointer scheme, so path reconstruction and the cost representation stay consistent withdijkstra.Notes
predecessorscall reports for an edge must match the costsuccessorsreports for that same edge; this is documented on the function. For an undirected graph that falls out naturally.Tests
dijkstra_bidirectional_path_ok/dijkstra_bidirectional_no_pathon the existing maze fixture, mirroring thebfs_bidirectionaltests, cross-checking the cost against unidirectionaldijkstra.dijkstra_bidirectional_okon the weighted directed graph fixture (with a reversedpredecessorsfunction), checking reachability, optimal cost, and that the returned path is a genuine walk whose edges sum to the reported cost.dijkstra; costs and reconstructed paths matched in every case. That harness isn't included in the PR.An
examples/dijkstra_bidirectional.rscompares it against plaindijkstraon a large weighted grid (centre to corner), in the same spirit as the existingbfs_bidirectionalexample.cargo fmt --all --check,cargo clippy --all-targetsand the full test suite (incl. doc tests) are clean.