|
23 | 23 | return digraph |
24 | 24 | end |
25 | 25 |
|
| 26 | +@traitfn function directed_graph(graph::AbstractSimpleGraph::(!IsDirected)) |
| 27 | + digraph = directed_graph(typeof(graph))() |
| 28 | + for v in vertices(graph) |
| 29 | + add_vertex!(digraph) |
| 30 | + end |
| 31 | + for e in edges(graph) |
| 32 | + add_edge!(digraph, e) |
| 33 | + add_edge!(digraph, reverse(e)) |
| 34 | + end |
| 35 | + return digraph |
| 36 | +end |
| 37 | + |
26 | 38 | @traitfn undirected_graph(graph::::(!IsDirected)) = graph |
27 | 39 |
|
28 | 40 | # TODO: Handle metadata in a generic way |
@@ -53,6 +65,22 @@ function rename_vertices(g::AbstractGraph, name_map) |
53 | 65 | return rename_vertices(v -> name_map[v], g) |
54 | 66 | end |
55 | 67 |
|
| 68 | +function permute_vertices(graph::AbstractGraph, permutation::Vector) |
| 69 | + return subgraph(graph, vertices(graph)[permutation]) |
| 70 | +end |
| 71 | + |
| 72 | +# Uniform interface for `outneighbors`, `inneighbors`, and `all_neighbors` |
| 73 | +function _neighbors(graph::AbstractGraph, vertex; dir=:out) |
| 74 | + if dir == :out |
| 75 | + return outneighbors(graph, vertex) |
| 76 | + elseif dir == :in |
| 77 | + return inneighbors(graph, vertex) |
| 78 | + elseif dir == :both |
| 79 | + return all_neighbors(graph, vertex) |
| 80 | + end |
| 81 | + return error("`_neighbors(graph::AbstractGraph, vertex; dir)` with `dir = $(dir) not implemented. Use either `dir = :out`, `dir = :in`, or `dir = :both`.") |
| 82 | +end |
| 83 | + |
56 | 84 | # Returns just the edges of a directed graph, |
57 | 85 | # but both edge directions of an undirected graph. |
58 | 86 | # TODO: Move to NamedGraphs.jl |
@@ -162,10 +190,13 @@ function in_incident_edges(graph::AbstractGraph, vertex) |
162 | 190 | ] |
163 | 191 | end |
164 | 192 |
|
| 193 | +# TODO: Only return one set of `:out` edges for undirected graphs if `dir=:both`. |
165 | 194 | function all_incident_edges(graph::AbstractGraph, vertex) |
166 | 195 | return out_incident_edges(graph, vertex) ∪ in_incident_edges(graph, vertex) |
167 | 196 | end |
168 | 197 |
|
| 198 | +# TODO: Same as `edges(subgraph(graph, [vertex; neighbors(graph, vertex)]))`. |
| 199 | +# TODO: Only return one set of `:out` edges for undirected graphs if `dir=:both`. |
169 | 200 | """ |
170 | 201 | incident_edges(graph::AbstractGraph, vertex; dir=:out) |
171 | 202 |
|
@@ -221,11 +252,13 @@ end |
221 | 252 | end |
222 | 253 |
|
223 | 254 | # Paths for undirected tree-like graphs |
| 255 | +# TODO: Use `a_star`. |
224 | 256 | @traitfn function vertex_path(graph::::(!IsDirected), s, t) |
225 | 257 | dfs_tree_graph = dfs_tree(graph, t) |
226 | 258 | return vertex_path(dfs_tree_graph, s, t) |
227 | 259 | end |
228 | 260 |
|
| 261 | +# TODO: Use `a_star`. |
229 | 262 | @traitfn function edge_path(graph::::(!IsDirected), s, t) |
230 | 263 | dfs_tree_graph = dfs_tree(graph, t) |
231 | 264 | return edge_path(dfs_tree_graph, s, t) |
|
295 | 328 | end |
296 | 329 |
|
297 | 330 | # Paths for directed tree-like graphs |
| 331 | +# TODO: Use `a_star`, make specialized versions: |
| 332 | +# `vertex_path(graph::::IsTree, ...)` |
| 333 | +# or |
| 334 | +# `tree_vertex_path(graph, ...)` |
298 | 335 | @traitfn function vertex_path(graph::::IsDirected, s, t) |
| 336 | + # @assert is_tree(graph) |
299 | 337 | vertices = eltype(graph)[s] |
300 | 338 | while vertices[end] != t |
301 | 339 | parent = parent_vertex(graph, vertices[end]) |
|
305 | 343 | return vertices |
306 | 344 | end |
307 | 345 |
|
| 346 | +# TODO: Use `a_star`, make specialized versions: |
| 347 | +# `vertex_path(graph::::IsTree, ...)` |
| 348 | +# or |
| 349 | +# `tree_vertex_path(graph, ...)` |
308 | 350 | @traitfn function edge_path(graph::::IsDirected, s, t) |
| 351 | + # @assert is_tree(graph) |
309 | 352 | vertices = vertex_path(graph, s, t) |
310 | 353 | isnothing(vertices) && return nothing |
311 | 354 | pop!(vertices) |
312 | 355 | return [edgetype(graph)(vertex, parent_vertex(graph, vertex)) for vertex in vertices] |
313 | 356 | end |
| 357 | + |
| 358 | +function mincut_partitions( |
| 359 | + graph::AbstractGraph, |
| 360 | + distmx=weights(graph), |
| 361 | +) |
| 362 | + parts = groupfind(first(mincut(graph, distmx))) |
| 363 | + return parts[1], parts[2] |
| 364 | +end |
0 commit comments