Skip to content

Commit 12cd075

Browse files
committed
add non-allocating enumerate_paths!
1 parent 2ae1c18 commit 12cd075

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

src/shortestpaths/bellman-ford.jl

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,41 @@ to all other vertices. In addition, `enumerate_paths(state, v, d)` will return
116116
a vector representing the path from vertex `v` to vertex `d`.
117117
"""
118118
function enumerate_paths(state::AbstractPathState, vs::AbstractVector{<:Integer})
119-
parents = state.parents
120-
T = eltype(parents)
119+
T = eltype(state.parents)
120+
all_paths = Vector{T}[Vector{eltype(state.parents)}() for _ in 1:length(vs)]
121+
enumerate_paths!(all_paths, state, vs)
122+
end
123+
124+
enumerate_paths(state::AbstractPathState, v::Integer) = enumerate_paths(state, v:v)[1]
125+
function enumerate_paths(state::AbstractPathState)
126+
return enumerate_paths(state, 1:length(state.parents))
127+
end
128+
129+
"""
130+
enumerate_paths!(paths::AbstractVector{<:AbstractVector}, state, vs::AbstractVector{Int})
131+
132+
In-place version of [`enumerate_paths`](@ref).
133+
134+
`paths` must be a `Vector{Vectors{eltype(state.parents)}}`
121135
136+
`enumerate_paths!` should be more efficient when used in a loop,
137+
as the same memory can be used for each iteration.
138+
"""
139+
function enumerate_paths!(
140+
all_paths::AbstractVector{<:AbstractVector},
141+
state::AbstractPathState,
142+
vs::AbstractVector{<:Integer}
143+
)
144+
Base.require_one_based_indexing(all_paths)
145+
Base.require_one_based_indexing(vs)
146+
@assert length(all_paths) == length(vs)
147+
148+
parents = state.parents
149+
T = eltype(state.parents)
122150
num_vs = length(vs)
123-
all_paths = Vector{Vector{T}}(undef, num_vs)
151+
124152
for i in 1:num_vs
125-
all_paths[i] = Vector{T}()
153+
empty!(all_paths[i])
126154
index = T(vs[i])
127155
if parents[index] != 0 || parents[index] == index
128156
while parents[index] != 0
@@ -134,9 +162,4 @@ function enumerate_paths(state::AbstractPathState, vs::AbstractVector{<:Integer}
134162
end
135163
end
136164
return all_paths
137-
end
138-
139-
enumerate_paths(state::AbstractPathState, v::Integer) = enumerate_paths(state, [v])[1]
140-
function enumerate_paths(state::AbstractPathState)
141-
return enumerate_paths(state, [1:length(state.parents);])
142-
end
165+
end

0 commit comments

Comments
 (0)