Skip to content

Commit

Permalink
Better algorithm specification
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeyT1994 committed Oct 26, 2023
1 parent fbc3b90 commit 89d968c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 24 deletions.
42 changes: 26 additions & 16 deletions src/traversals/trees_and_forests.jl
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
abstract type SpanningTreeAlgorithm end

struct BFS <: SpanningTreeAlgorithm end
struct RandomBFS <: SpanningTreeAlgorithm end
struct DFS <: SpanningTreeAlgorithm end

default_spanning_tree_alg() = BFS()

default_root_vertex(g) = last(findmax(eccentricities(g)))

function spanning_tree(g::AbstractNamedGraph; root_vertex=default_root_vertex(g))
return spanning_tree(default_spanning_tree_alg(), g; root_vertex)
end

function spanning_tree(::BFS, g::AbstractNamedGraph; root_vertex=default_root_vertex(g))
@assert !NamedGraphs.is_directed(g)
return undirected_graph(bfs_tree(g, root_vertex))
end

function spanning_tree(
g::AbstractNamedGraph; root_vertex=default_root_vertex(g), alg::String="BFS"
::RandomBFS, g::AbstractNamedGraph; root_vertex=default_root_vertex(g)
)
@assert !NamedGraphs.is_directed(g)
if alg == "BFS"
return undirected_graph(bfs_tree(g, root_vertex))
elseif alg == "RandomBFS"
return undirected_graph(random_bfs_tree(g, root_vertex))
elseif alg == "DFS"
return undirected_graph(dfs_tree(g, root_vertex))
else
error("Algorithm not current supported")
end
return undirected_graph(random_bfs_tree(g, root_vertex))
end

function spanning_tree(::DFS, g::AbstractNamedGraph; root_vertex=default_root_vertex(g))
@assert !NamedGraphs.is_directed(g)
return undirected_graph(dfs_tree(g, root_vertex))
end

#Given a graph, split it into its connected components, construct a spanning tree over each of them
# and take the union.
function spanning_forest(
g::AbstractNamedGraph; spanning_tree_function=g -> spanning_tree(g)
)
function spanning_forest(g::AbstractNamedGraph; spanning_tree_function=spanning_tree)
return reduce(union, (spanning_tree_function(g[vs]) for vs in connected_components(g)))
end

#Given an undirected graph g with vertex set V, build a set of forests (each with vertex set V) which covers all edges in g
# (see https://en.wikipedia.org/wiki/Arboricity) We do not find the minimum but our tests show this algorithm performs well
function build_forest_cover(
g::AbstractNamedGraph; spanning_tree_function=g -> spanning_tree(g)
)
function forest_cover(g::AbstractNamedGraph; spanning_tree_function=spanning_tree)
edges_collected = edgetype(g)[]
remaining_edges = edges(g)
forests = NamedGraph[]
Expand Down
16 changes: 8 additions & 8 deletions test/test_trees_and_forests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Test
using Graphs
using NamedGraphs
using NamedGraphs:
hexagonal_lattice_graph, triangular_lattice_graph, build_forest_cover, spanning_tree
hexagonal_lattice_graph, triangular_lattice_graph, forest_cover, spanning_tree

@testset "Test Spanning Trees" begin
gs = [
Expand All @@ -13,10 +13,10 @@ using NamedGraphs:
named_grid((10, 10)),
triangular_lattice_graph(5, 5; periodic=true),
]
algs = ["BFS", "DFS", "RandomBFS"]
algs = [NamedGraphs.BFS(), NamedGraphs.DFS(), NamedGraphs.RandomBFS()]
for g in gs
for alg in algs
s_tree = spanning_tree(g; alg)
s_tree = spanning_tree(alg, g)
@test is_tree(s_tree)
@test Set(vertices(s_tree)) == Set(vertices(g))
@test issubset(Set(edges(s_tree)), Set(edges(g)))
Expand All @@ -34,12 +34,12 @@ end
triangular_lattice_graph(5, 5; periodic=true),
]
for g in gs
forest_cover = build_forest_cover(g)
cover_edges = reduce(vcat, edges.(forest_cover))
cover = forest_cover(g)
cover_edges = reduce(vcat, edges.(cover))
@test issetequal(cover_edges, edges(g))
@test all(issetequal(vertices(f), vertices(g)) for f in forest_cover)
for f in forest_cover
trees = NamedGraph[f[vs] for vs in connected_components(f)]
@test all(issetequal(vertices(forest), vertices(g)) for forest in cover)
for forest in cover
trees = NamedGraph[forest[vs] for vs in connected_components(forest)]
@test all(is_tree.(trees))
end
end
Expand Down

0 comments on commit 89d968c

Please sign in to comment.