Skip to content

Commit

Permalink
Improve docstrings for all shortest path states (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
gdalle authored Sep 14, 2023
1 parent 6e47549 commit 15e6640
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 35 deletions.
4 changes: 3 additions & 1 deletion src/shortestpaths/astar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@ end
Compute a shortest path using the [A* search algorithm](http://en.wikipedia.org/wiki/A%2A_search_algorithm).
Return a vector of edges.
# Arguments
- `g::AbstractGraph`: the graph
- `s::Integer`: the source vertex
- `t::Integer`: the target vertex
- `distmx::AbstractMatrix`: an optional (possibly sparse) `n × n` matrix of edge weights. It is set to `weights(g)` by default (which itself falls back on [`Graphs.DefaultDistance`](@ref)).
- `heuristic`: an optional function mapping each vertex to a lower estimate of the remaining distance from `v` to `t`. It is set to `v -> 0` by default (which corresponds to Dijkstra's algorithm). Note that the heuristic values should have the same type as the edge weights!
- `edgetype_to_return::Type{E}`: the eltype `E<:AbstractEdge` of the vector of edges returned. It is set to `edgetype(g)` by default. Note that the two-argument constructor `E(u, v)` must be defined, even for weighted edges: if it isn't, consider using `E = Graphs.SimpleEdge`.
- `edgetype_to_return::Type{E}`: the type `E<:AbstractEdge` of the edges in the return vector. It is set to `edgetype(g)` by default. Note that the two-argument constructor `E(u, v)` must be defined, even for weighted edges: if it isn't, consider using `E = Graphs.SimpleEdge`.
"""
function a_star(
g::AbstractGraph{U}, # the g
Expand Down
8 changes: 7 additions & 1 deletion src/shortestpaths/bellman-ford.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ struct NegativeCycleError <: Exception end
BellmanFordState{T, U}
An `AbstractPathState` designed for Bellman-Ford shortest-paths calculations.
# Fields
- `parents::Vector{U}`: `parents[v]` is the predecessor of vertex `v` on the shortest path from the source to `v`
- `dists::Vector{T}`: `dists[v]` is the length of the shortest path from the source to `v`
"""
struct BellmanFordState{T<:Real,U<:Integer} <: AbstractPathState
parents::Vector{U}
Expand All @@ -29,7 +34,8 @@ end
Compute shortest paths between a source `s` (or list of sources `ss`) and all
other nodes in graph `g` using the [Bellman-Ford algorithm](http://en.wikipedia.org/wiki/Bellman–Ford_algorithm).
Return a [`Graphs.BellmanFordState`](@ref) with relevant traversal information.
Return a [`Graphs.BellmanFordState`](@ref) with relevant traversal information (try querying `state.parents` or `state.dists`).
"""
function bellman_ford_shortest_paths(
graph::AbstractGraph{U},
Expand Down
7 changes: 6 additions & 1 deletion src/shortestpaths/desopo-pape.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
struct DEposoPapeState{T, U}
An [`AbstractPathState`](@ref) designed for D`Esopo-Pape shortest-path calculations.
# Fields
- `parents::Vector{U}`: `parents[v]` is the predecessor of vertex `v` on the shortest path from the source to `v`
- `dists::Vector{T}`: `dists[v]` is the length of the shortest path from the source to `v`
"""
struct DEsopoPapeState{T<:Real,U<:Integer} <: AbstractPathState
parents::Vector{U}
Expand All @@ -13,7 +18,7 @@ end
Compute shortest paths between a source `src` and all
other nodes in graph `g` using the [D'Esopo-Pape algorithm](http://web.mit.edu/dimitrib/www/SLF.pdf).
Return a [`Graphs.DEsopoPapeState`](@ref) with relevant traversal information.
Return a [`Graphs.DEsopoPapeState`](@ref) with relevant traversal information (try querying `state.parents` or `state.dists`).
# Examples
```jldoctest
Expand Down
32 changes: 14 additions & 18 deletions src/shortestpaths/dijkstra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
struct DijkstraState{T, U}
An [`AbstractPathState`](@ref) designed for Dijkstra shortest-paths calculations.
# Fields
- `parents::Vector{U}`
- `dists::Vector{T}`
- `predecessors::Vector{Vector{U}}`: a vector, indexed by vertex, of all the predecessors discovered during shortest-path calculations. This keeps track of all parents when there are multiple shortest paths available from the source.
- `pathcounts::Vector{Float64}`: a vector, indexed by vertex, of the number of shortest paths from the source to that vertex. The path count of a source vertex is always `1.0`. The path count of an unreached vertex is always `0.0`.
- `closest_vertices::Vector{U}`: a vector of all vertices in the graph ordered from closest to farthest.
"""
struct DijkstraState{T<:Real,U<:Integer} <: AbstractPathState
parents::Vector{U}
Expand All @@ -16,23 +24,12 @@ end
Perform [Dijkstra's algorithm](http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)
on a graph, computing shortest distances between `srcs` and all other vertices.
Return a [`Graphs.DijkstraState`](@ref) that contains various traversal information.
Return a [`Graphs.DijkstraState`](@ref) that contains various traversal information (try querying `state.parents` or `state.dists`).
### Optional Arguments
* `allpaths=false`: If true,
`state.predecessors` holds a vector, indexed by vertex,
of all the predecessors discovered during shortest-path calculations.
This keeps track of all parents when there are multiple shortest paths available from the source.
`state.pathcounts` holds a vector, indexed by vertex, of the number of shortest paths from the source to that vertex.
The path count of a source vertex is always `1.0`. The path count of an unreached vertex is always `0.0`.
* `trackvertices=false`: If true,
`state.closest_vertices` holds a vector of all vertices in the graph ordered from closest to farthest.
* `allpaths=false`: If true, `state.pathcounts` holds a vector, indexed by vertex, of the number of shortest paths from the source to that vertex. The path count of a source vertex is always `1.0`. The path count of an unreached vertex is always `0.0`.
* `trackvertices=false`: If true, `state.closest_vertices` holds a vector of all vertices in the graph ordered from closest to farthest.
* `maxdist` (default: `typemax(T)`) specifies the maximum path distance beyond which all path distances are assumed to be infinite (that is, they do not exist).
### Performance
Expand Down Expand Up @@ -75,9 +72,8 @@ function dijkstra_shortest_paths(
distmx::AbstractMatrix{T}=weights(g);
allpaths=false,
trackvertices=false,
maxdist=typemax(T)
) where T <: Real where U <: Integer

maxdist=typemax(T),
) where {T<:Real} where {U<:Integer}
nvg = nv(g)
dists = fill(typemax(T), nvg)
parents = zeros(U, nvg)
Expand Down Expand Up @@ -163,7 +159,7 @@ function dijkstra_shortest_paths(
distmx::AbstractMatrix=weights(g);
allpaths=false,
trackvertices=false,
maxdist=typemax(eltype(distmx))
maxdist=typemax(eltype(distmx)),
)
return dijkstra_shortest_paths(
g, [src;], distmx; allpaths=allpaths, trackvertices=trackvertices, maxdist=maxdist
Expand Down
10 changes: 7 additions & 3 deletions src/shortestpaths/floyd-warshall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
struct FloydWarshallState{T, U}
An [`AbstractPathState`](@ref) designed for Floyd-Warshall shortest-paths calculations.
# Fields
- `dists::Matrix{T}`: `dists[u, v]` is the length of the shortest path from `u` to `v`
- `parents::Matrix{U}`: `parents[u, v]` is the predecessor of vertex `v` on the shortest path from `u` to `v`
"""
struct FloydWarshallState{T,U<:Integer} <: AbstractPathState
dists::Matrix{T}
Expand All @@ -15,11 +20,10 @@ end
Use the [Floyd-Warshall algorithm](http://en.wikipedia.org/wiki/Floyd–Warshall_algorithm)
to compute the shortest paths between all pairs of vertices in graph `g` using an
optional distance matrix `distmx`. Return a [`Graphs.FloydWarshallState`](@ref) with relevant
traversal information.
optional distance matrix `distmx`. Return a [`Graphs.FloydWarshallState`](@ref) with relevant traversal information (try querying `state.parents` or `state.dists`).
### Performance
Space complexity is on the order of ``\\mathcal{O}(|V|^2)``.
Space complexity is on the order of `O(|V|^2)`.
"""
function floyd_warshall_shortest_paths(
g::AbstractGraph{U}, distmx::AbstractMatrix{T}=weights(g)
Expand Down
12 changes: 9 additions & 3 deletions src/shortestpaths/johnson.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
struct JohnsonState{T, U}
An [`AbstractPathState`](@ref) designed for Johnson shortest-paths calculations.
# Fields
- `dists::Matrix{T}`: `dists[u, v]` is the length of the shortest path from `u` to `v`
- `parents::Matrix{U}`: `parents[u, v]` is the predecessor of vertex `v` on the shortest path from `u` to `v`
"""
struct JohnsonState{T<:Real,U<:Integer} <: AbstractPathState
dists::Matrix{T}
Expand All @@ -17,18 +22,19 @@ to compute the shortest paths between all pairs of vertices in graph `g` using a
optional distance matrix `distmx`.
Return a [`Graphs.JohnsonState`](@ref) with relevant
traversal information.
traversal information (try querying `state.parents` or `state.dists`).
### Performance
Complexity: O(|V|*|E|)
Complexity: `O(|V|*|E|)`
"""
function johnson_shortest_paths(
g::AbstractGraph{U}, distmx::AbstractMatrix{T}=weights(g)
) where {T<:Real} where {U<:Integer}
nvg = nv(g)
type_distmx = typeof(distmx)
# Change when parallel implementation of Bellman Ford available
wt_transform = bellman_ford_shortest_paths(g, collect_if_not_vector(vertices(g)), distmx).dists
wt_transform =
bellman_ford_shortest_paths(g, collect_if_not_vector(vertices(g)), distmx).dists

@compat if !ismutable(distmx) && type_distmx != Graphs.DefaultDistance
distmx = sparse(distmx) # Change reference, not value
Expand Down
2 changes: 2 additions & 0 deletions src/shortestpaths/spfa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Compute shortest paths between a source `s` and all
other nodes in graph `g` using the [Shortest Path Faster Algorithm]
(https://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm).
Return a vector of distances to the source.
# Examples
```jldoctest
Expand Down
20 changes: 12 additions & 8 deletions src/shortestpaths/yen.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# TODO this algorithm does not work with abitrary AbstractGraph yet,
# as it relies on rem_edge! and deepcopy


"""
struct YenState{T, U}
Designed for yen k-shortest-paths calculations.
# Fields
- `dists::Vector{T}`: `dists[k]` is the length of the `k`-th shortest path from the source to the target
- `paths::Vector{Vector{U}}`: `paths[k]` is the description of the `k`-th shortest path (as a sequence of vertices) from the source to the target
"""
struct YenState{T,U<:Integer} <: AbstractPathState
dists::Vector{T}
Expand All @@ -25,8 +29,8 @@ function yen_k_shortest_paths(
target::U,
distmx::AbstractMatrix{T}=weights(g),
K::Int=1;
maxdist=typemax(T)) where {T<:Real} where {U<:Integer}

maxdist=typemax(T),
) where {T<:Real} where {U<:Integer}
source == target && return YenState{T,U}([U(0)], [[source]])

dj = dijkstra_shortest_paths(g, source, distmx; maxdist)
Expand All @@ -39,7 +43,7 @@ function yen_k_shortest_paths(
B = PriorityQueue()
gcopy = deepcopy(g)

for k in 1:(K-1)
for k in 1:(K - 1)
for j in 1:length(A[k])
# Spur node is retrieved from the previous k-shortest path, k − 1
spurnode = A[k][j]
Expand All @@ -52,7 +56,7 @@ function yen_k_shortest_paths(
for ppath in A
if length(ppath) > j && rootpath == ppath[1:j]
u = ppath[j]
v = ppath[j+1]
v = ppath[j + 1]
if has_edge(gcopy, u, v)
rem_edge!(gcopy, u, v)
push!(edgesremoved, (u, v))
Expand All @@ -62,7 +66,7 @@ function yen_k_shortest_paths(

# Remove node of root path and calculate dist of it
distrootpath = zero(T)
for n in 1:(length(rootpath)-1)
for n in 1:(length(rootpath) - 1)
u = rootpath[n]
nei = copy(neighbors(gcopy, u))
for v in nei
Expand All @@ -71,7 +75,7 @@ function yen_k_shortest_paths(
end

# Evaluate distance of root path
v = rootpath[n+1]
v = rootpath[n + 1]
distrootpath += distmx[u, v]
end

Expand All @@ -80,7 +84,7 @@ function yen_k_shortest_paths(
spurpath = enumerate_paths(djspur)[target]
if !isempty(spurpath)
# Entire path is made up of the root path and spur path
pathtotal = [rootpath[1:(end-1)]; spurpath]
pathtotal = [rootpath[1:(end - 1)]; spurpath]
distpath = distrootpath + djspur.dists[target]
# Add the potential k-shortest path to the heap
if !haskey(B, pathtotal)
Expand Down

0 comments on commit 15e6640

Please sign in to comment.