diff --git a/src/spanningtrees/kruskal.jl b/src/spanningtrees/kruskal.jl index f92ba5beb..270cfae65 100644 --- a/src/spanningtrees/kruskal.jl +++ b/src/spanningtrees/kruskal.jl @@ -1,12 +1,15 @@ """ - kruskal_mst(g, distmx=weights(g)) -Return a vector of edges representing the minimum spanning tree of a connected, undirected graph `g` with optional + kruskal_mst(g, distmx=weights(g); minimize=true) +Return a vector of edges representing the minimum (by default) spanning tree of a connected, undirected graph `g` with optional distance matrix `distmx` using [Kruskal's algorithm](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm). + +### Optional Arguments +- `minimize=true`: if set to `false`, calculate the maximum spanning tree. """ function kruskal_mst end # see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax @traitfn function kruskal_mst(g::AG::(!IsDirected), - distmx::AbstractMatrix{T}=weights(g)) where {T <: Real, U, AG <: AbstractGraph{U}} + distmx::AbstractMatrix{T}=weights(g); minimize=true) where {T <: Real, U, AG <: AbstractGraph{U}} connected_vs = IntDisjointSets(nv(g)) @@ -20,7 +23,7 @@ function kruskal_mst end push!(weights, distmx[src(e), dst(e)]) end - for e in edge_list[sortperm(weights)] + for e in edge_list[sortperm(weights; rev=!minimize)] if !in_same_set(connected_vs, src(e), dst(e)) union!(connected_vs, src(e), dst(e)) push!(mst, e) diff --git a/test/spanningtrees/kruskal.jl b/test/spanningtrees/kruskal.jl index 3ed3d6bfa..29ccfaf96 100644 --- a/test/spanningtrees/kruskal.jl +++ b/test/spanningtrees/kruskal.jl @@ -9,10 +9,12 @@ ] vec_mst = Vector{Edge}([Edge(1, 2), Edge(3, 4), Edge(2, 3)]) + max_vec_mst = Vector{Edge}([Edge(2, 4), Edge(1, 4), Edge(1, 3)]) for g in testgraphs(g4) # Testing Kruskal's algorithm mst = @inferred(kruskal_mst(g, distmx)) @test mst == vec_mst + @test @inferred(kruskal_mst(g, distmx, minimize=false)) == max_vec_mst end #second test distmx_sec = [ @@ -28,8 +30,10 @@ gx = SimpleGraph(distmx_sec) vec2 = Vector{Edge}([Edge(1, 8), Edge(3, 4), Edge(2, 8), Edge(1, 3), Edge(6, 8), Edge(5, 6), Edge(3, 7)]) + max_vec2 = Vector{Edge}([Edge(5, 7), Edge(1, 7), Edge(4, 7), Edge(3, 7), Edge(5, 8), Edge(2, 3), Edge(5, 6)]) for g in testgraphs(gx) mst2 = @inferred(kruskal_mst(g, distmx_sec)) @test mst2 == vec2 + @test @inferred(kruskal_mst(g, distmx_sec, minimize=false)) == max_vec2 end end