@@ -107,6 +107,7 @@ single destinations, the path is represented by a single vector of vertices,
107
107
and will be length 0 if the path does not exist.
108
108
109
109
### Implementation Notes
110
+
110
111
For Floyd-Warshall path states, please note that the output is a bit different,
111
112
since this algorithm calculates all shortest paths for all pairs of vertices:
112
113
`enumerate_paths(state)` will return a vector (indexed by source vertex) of
@@ -116,13 +117,47 @@ to all other vertices. In addition, `enumerate_paths(state, v, d)` will return
116
117
a vector representing the path from vertex `v` to vertex `d`.
117
118
"""
118
119
function enumerate_paths (state:: AbstractPathState , vs:: AbstractVector{<:Integer} )
119
- parents = state. parents
120
- T = eltype (parents)
120
+ T = eltype (state. parents)
121
+ all_paths = Vector{T}[Vector {eltype(state.parents)} () for _ in 1 : length (vs)]
122
+ return enumerate_paths! (all_paths, state, vs)
123
+ end
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)}}`, `state` an `AbstractPathState`,
135
+ and `vs`` an AbstractRange or other AbstractVector of `Int`.
121
136
137
+ See the `enumerate_paths` documentation for details.
138
+
139
+ `enumerate_paths!` should be more efficient when used in a loop,
140
+ as the same memory can be used for each iteration.
141
+ """
142
+ function enumerate_paths! (
143
+ all_paths:: AbstractVector{<:AbstractVector} ,
144
+ state:: AbstractPathState ,
145
+ vs:: AbstractVector{<:Integer} ,
146
+ )
147
+ Base. require_one_based_indexing (all_paths)
148
+ Base. require_one_based_indexing (vs)
149
+ length (all_paths) == length (vs) || throw (
150
+ ArgumentError (
151
+ " length of destination paths $(length (vs)) deos not match length of vs $(length (all_paths)) " ,
152
+ ),
153
+ )
154
+
155
+ parents = state. parents
156
+ T = eltype (state. parents)
122
157
num_vs = length (vs)
123
- all_paths = Vector {Vector{T}} (undef, num_vs)
158
+
124
159
for i in 1 : num_vs
125
- all_paths[i] = Vector {T} ( )
160
+ empty! ( all_paths[i])
126
161
index = T (vs[i])
127
162
if parents[index] != 0 || parents[index] == index
128
163
while parents[index] != 0
@@ -135,8 +170,3 @@ function enumerate_paths(state::AbstractPathState, vs::AbstractVector{<:Integer}
135
170
end
136
171
return all_paths
137
172
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
0 commit comments