diff --git a/src/JunctionTrees.jl b/src/JunctionTrees.jl index dac274c..b200de6 100644 --- a/src/JunctionTrees.jl +++ b/src/JunctionTrees.jl @@ -12,11 +12,11 @@ using SparseArrays # Orders -export Order +export Order, inverse # Elimination Algorithms -export AMDJL_AMD, CuthillMcKeeJL_RCM, MetisJL_ND +export AMDJL_AMD, CuthillMcKeeJL_RCM, MetisJL_ND, MCS # Supernode Types @@ -24,7 +24,7 @@ export Node, Maximal, Fundamental # Supernode Trees -export SupernodeTree, width, height, seperators, supernode, permutation, inverse +export SupernodeTree, width, height, seperators, supernode, permutation include("junction_trees/orders.jl") diff --git a/src/junction_trees/elimination_algorithms.jl b/src/junction_trees/elimination_algorithms.jl index 9d273e9..79a2b77 100644 --- a/src/junction_trees/elimination_algorithms.jl +++ b/src/junction_trees/elimination_algorithms.jl @@ -5,7 +5,7 @@ A graph elimination algorithm. The options are - [`CuthillMcKeeJL_RCM`](@ref) - [`AMDJL_AMD`](@ref) - [`MetisJL_ND`](@ref) -- [`Order`](@ref) +- [`MCS`](@ref) """ abstract type EliminationAlgorithm end @@ -34,6 +34,14 @@ The nested dissection heuristic. Uses Metis.jl. struct MetisJL_ND <: EliminationAlgorithm end +""" + MCS <: EliminationAlgorithm + +The maximum cardinality search algorithm. +""" +struct MCS <: EliminationAlgorithm end + + # Construct an order using the default graph elimination algorithm. function Order(graph::AbstractSymmetricGraph) Order(graph, DEFAULT_ELIMINATION_ALGORITHM) @@ -63,6 +71,13 @@ function Order(graph::AbstractSymmetricGraph, ealg::MetisJL_ND) end +# Concstruct an order using the maximum cardinality search algorithm. +function Order(graph::AbstractSymmetricGraph, ealg::MCS) + order, index = mcs(graph) + Order(order, index) +end + + # Construct the adjacency matrix of a graph. function adjacencymatrix(graph::AbstractSymmetricGraph) m = ne(graph) @@ -83,4 +98,52 @@ function adjacencymatrix(graph::AbstractSymmetricGraph) end +# Simple Linear-Time Algorithms to Test Chordality of Graphs, Test Acyclicity +# of Hypergraphs, and Selectively Reduce Acyclic Hypergraphs +# +# Tarjan and Yannakakis +# +# Maximum Cardinality Search +function mcs(graph::AbstractSymmetricGraph) + n = nv(graph) + α = Vector{Int}(undef, n) + α⁻¹ = Vector{Int}(undef, n) + size = Vector{Int}(undef, n) + set = Vector{Set{Int}}(undef, n) + + for i in 1:n + size[i] = 1 + set[i] = Set() + end + + union!(set[1], 1:n) + + i = n + j = 1 + + while i >= 1 + v = pop!(set[j]) + α[v] = i + α⁻¹[i] = v + size[v] = 0 + + for w in neighbors(graph, v) + if size[w] >= 1 + delete!(set[size[w]], w) + size[w] += 1 + push!(set[size[w]], w) + end + end + + i -= 1 + j += 1 + + while j >= 1 && isempty(set[j]) + j -= 1 + end + end + + α⁻¹, α +end + const DEFAULT_ELIMINATION_ALGORITHM = AMDJL_AMD() diff --git a/test/JunctionTrees.jl b/test/JunctionTrees.jl index f3829a5..5216571 100644 --- a/test/JunctionTrees.jl +++ b/test/JunctionTrees.jl @@ -25,6 +25,9 @@ order = JunctionTrees.Order(graph, AMDJL_AMD()) order = JunctionTrees.Order(graph, MetisJL_ND()) @test length(order) == 17 +order = JunctionTrees.Order(graph, MCS()) +@test length(order) == 17 + order = JunctionTrees.Order(1:17) @test length(order) == 17