-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
two sided dijkstra #268
base: master
Are you sure you want to change the base?
two sided dijkstra #268
Conversation
I added a very simple test, not sure if it is sufficient |
Tests are failing because of #271 which has now been merged. If we merge the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good contribution, thanks! The tests will probably fail because of formatting alone, so be sure to install JuliaFormatter.jl in your global environment (@v1.9
) and then to run using JuliaFormatter; format(".")
from the root of your fork of Graphs.jl
src/shortestpaths/dijkstra.jl
Outdated
end | ||
# keep weight of the best seen path and the midpoint vertex | ||
mu, mid_v = typemax(T), -1 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All that white space may not be necessary
uf, ub = dequeue!(Qf), dequeue!(Qb) | ||
|
||
for v in outneighbors(g, uf) | ||
relax(uf, v, distmx, dists_f, parents_f, visited_f, Qf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This relax function clarifies things, would it be hard to add it to the original dijkstra
too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping you would notice =p I'll make the changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a new version of the relax
function that should work for both the dijkstra_shortest_paths
and bidijkstra_shortest_path
but it is a bit clunky. I am wondering; why the need for the parents
and preds
structures ? wouldn't the list of predecessors be enough ?
A cosmetic note: should we rename the function the bidijkstra_shortest_paths
if it should be able to deal with multiple paths ?
src/shortestpaths/dijkstra.jl
Outdated
end | ||
ds_f = DijkstraState{T,U}(parents_f, dists_f, preds_f, zeros(nvg), Vector{U}()) | ||
ds_b = DijkstraState{T,U}(parents_b, dists_b, preds_b, zeros(nvg), Vector{U}()) | ||
path = vcat(enumerate_paths(ds_f, mid_v), reverse(enumerate_paths(ds_b, mid_v)[1:end-1])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if there are several paths?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to deal with such situations, as far as I can tell multiple paths with the same cost can be detected if the condition mu == ls + lt
is reached. I'll look into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that bidijkstra_shortest_path
only returns src
-dst
-paths it doesn't make much sense to keep a full list of predecessors, does it ? I am not sure what the most elegant way to deal with these situations, especially when trying to share code with dijkstra_shortest_paths
.
I've also noticed that there doesn't seem to be a straightforward way to retrieve multiple paths for a single (src,dst)
pair. As far a I can tell the enumerate_paths
routine returns a single path per destination. Should this be addressed at some point ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The additional dependencies are not acceptable, and it needs more tests, but it's a solid start!
Not sure why tests are failing |
I think your modification to Dijkstra somehow broke a test in the centrality part of the package.
The error comes from the following test: # test #1405 / #1406
g = GenericGraph(grid([50, 50]))
z = betweenness_centrality(g; normalize=false)
@test maximum(z) < nv(g) * (nv(g) - 1) and it looks like this:
It is related to the following issue in the old LightGraphs.jl package |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be some different behavior for the pathcount
when using dijkstra_shortest_path
. Might be some kind of overflow issue, as I only saw it on large graphs so far.
before:
julia> dijkstra_shortest_paths(grid([50, 50]), 1).pathcounts[50*50]
2.5477612258980867e28
after:
julia> dijkstra_shortest_paths(grid([50, 50]), 1).pathcounts[50*50]
8.581105107791177e17
I think the right solution here should be (2 * 49 \choose 49)
, i.e
julia> binomial(BigInt(2*49), 49)
25477612258980856902730428600
so apart from some rounding errors, the old solution looks much more correct to me.
src/shortestpaths/dijkstra.jl
Outdated
@@ -83,7 +83,7 @@ function dijkstra_shortest_paths( | |||
parents = zeros(U, nvg) | |||
visited = zeros(Bool, nvg) | |||
|
|||
pathcounts = zeros(nvg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably should not change this, it might overflow.
It also look to me, as if those changes might make the algorithm perform slower than before, but I only checked this single case: julia> @btime dijkstra_shortest_paths($(grid([50, 50])), 1);
548.740 μs (81 allocations: 165.11 KiB) after julia> @btime dijkstra_shortest_paths($(grid([50, 50])), 1);
585.437 μs (83 allocations: 184.72 KiB) |
…destination of the shortest path
…on), tests now work
@Dolgalad is this ready for another round of review? sorry for the delay |
Implemented the Two sided Dijkstra algorithm, still requires documentation and tests