Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added forest cover function #39

Merged
merged 14 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/traversals/dfs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,32 @@ end
function dfs_parents(graph::AbstractNamedGraph, vertex; kwargs...)
return _dfs_parents(graph, vertex; kwargs...)
end

#Given a graph, split it into its connected components, construct a spanning tree over each of them
# and take the union (adding in edges between the trees to recover a connected graph)
function spanning_forest(g::AbstractNamedGraph)
components = connected_components(g)
return reduce(
union,
NamedGraph[
undirected_graph(bfs_tree(g[g_comp], first(g_comp))) for g_comp in components
],
)
JoeyT1994 marked this conversation as resolved.
Show resolved Hide resolved
end

#Given a 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)
edges_collected = edgetype(g)[]
remaining_edges = edges(g)
forests = NamedGraph[]
while !isempty(remaining_edges)
g_reduced = rem_edges(g, edges_collected)
g_reduced_spanning_forest = spanning_forest(g_reduced)
push!(edges_collected, edges(g_reduced_spanning_forest)...)
push!(forests, g_reduced_spanning_forest)
setdiff!(remaining_edges, edges(g_reduced_spanning_forest))
end

return forests
end
30 changes: 30 additions & 0 deletions test/test_forests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Test
using Graphs
using NamedGraphs
using NamedGraphs:
decorate_graph_edges,
decorate_graph_vertices,
hexagonal_lattice_graph,
triangular_lattice_graph,
build_forest_cover

@testset "Test Forest Cover" begin
gs = [
named_grid((6, 1)),
named_grid((3, 3, 3)),
hexagonal_lattice_graph(6, 6),
named_comb_tree((4, 4)),
named_grid((10, 10)),
triangular_lattice_graph(5, 5; periodic=true),
]
for g in gs
forest_cover = build_forest_cover(g)
cover_edges = reduce(vcat, edges.(forest_cover))
@test issetequal(cover_edges, edges(g))
for f in forest_cover
trees = NamedGraph[f[vs] for vs in connected_components(f)]
@test all(is_tree.(trees))
@test issetequal(vertices(f), vertices(g))
end
end
end
1 change: 0 additions & 1 deletion test/test_namedgraphgenerators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ using Random
@test dims[1] > dims[2]

g = triangular_lattice_graph(2, 1)
@show g
dims = maximum(vertices(g))
@test dims[1] > dims[2]

Expand Down