Skip to content
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[weakdeps]
CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"

[extensions]
SparseMatrixColoringsCliqueTreesExt = "CliqueTrees"
SparseMatrixColoringsColorsExt = "Colors"

[compat]
ADTypes = "1.2.1"
CliqueTrees = "0.5.2"
Colors = "0.12.11, 0.13"
DataStructures = "0.18"
DocStringExtensions = "0.8,0.9"
Expand Down
36 changes: 36 additions & 0 deletions ext/SparseMatrixColoringsCliqueTreesExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module SparseMatrixColoringsCliqueTreesExt

using CliqueTrees: CliqueTrees
Comment thread
samuelsonric marked this conversation as resolved.
Outdated
using SparseArrays
Comment thread
samuelsonric marked this conversation as resolved.
Outdated
using SparseMatrixColorings:
SparseMatrixColorings, AdjacencyGraph, BipartiteGraph, PerfectEliminationOrder, pattern

function SparseMatrixColorings.vertices(
g::AdjacencyGraph{T}, order::PerfectEliminationOrder
) where {T}
S = pattern(g)
Comment thread
samuelsonric marked this conversation as resolved.
Outdated

# construct matrix with sparsity pattern S
M = SparseMatrixCSC{Bool,T}(size(S)..., S.colptr, rowvals(S), ones(Bool, nnz(S)))

# can also use alg=CliqueTrees.LexBFS()
order, _ = CliqueTrees.permutation(M; alg=CliqueTrees.MCS())

return reverse!(order)
end

function SparseMatrixColorings.vertices(
bg::BipartiteGraph{T}, ::Val{side}, order::PerfectEliminationOrder
) where {T,side}
S = pattern(bg, Val(side))

# construct matrix with sparsity pattern S
M = SparseMatrixCSC{Bool,T}(size(S)..., S.colptr, rowvals(S), ones(Bool, nnz(S)))
Comment thread
samuelsonric marked this conversation as resolved.

# can also use alg=CliqueTrees.LexBFS()
order, _ = CliqueTrees.permutation(M; alg=CliqueTrees.MCS())

return reverse!(order)
end

end # module
1 change: 1 addition & 0 deletions src/SparseMatrixColorings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ include("show_colors.jl")

export NaturalOrder, RandomOrder, LargestFirst
export DynamicDegreeBasedOrder, SmallestLast, IncidenceDegree, DynamicLargestFirst
export PerfectEliminationOrder
export ColoringProblem, GreedyColoringAlgorithm, AbstractColoringResult
export ConstantColoringAlgorithm
export coloring, fast_coloring
Expand Down
14 changes: 14 additions & 0 deletions src/order.jl
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,17 @@ Instance of [`AbstractOrder`](@ref) which sorts vertices from lowest to highest
- [`DynamicDegreeBasedOrder`](@ref)
"""
const DynamicLargestFirst = DynamicDegreeBasedOrder{:forward,:low2high}

"""
PerfectEliminationOrder

Instance of [`AbstractOrder`](@ref) which sorts the vertices of a chordal graph in a perfect elimination order.
Comment thread
samuelsonric marked this conversation as resolved.
Outdated

!!! danger
This order is implemented as a package extension and requires loading CliqueTrees.jl.
Comment thread
samuelsonric marked this conversation as resolved.
Outdated

# References

- [Simple Linear-Time Algorithms to Test Chordality of Graphs, Test Acyclicity of Hypergraphs, and Selectively Reduce Acyclic Hypergraphs](https://epubs.siam.org/doi/10.1137/0213035), Tarjan and Yannakakis (1984)
"""
struct PerfectEliminationOrder <: AbstractOrder end
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Chairmarks = "0ca39b1e-fe0b-4e98-acfc-b1656634c4de"
CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Expand Down
18 changes: 18 additions & 0 deletions test/order.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using CliqueTrees: CliqueTrees
using BandedMatrices
using LinearAlgebra
using SparseArrays
using SparseMatrixColorings
Expand All @@ -7,6 +9,7 @@ using SparseMatrixColorings:
LargestFirst,
NaturalOrder,
RandomOrder,
PerfectEliminationOrder,
degree_dist2,
nb_vertices,
valid_dynamic_order,
Expand Down Expand Up @@ -110,3 +113,18 @@ end;
end
end
end;

@testset "PerfectEliminationOrder" begin
problem1 = ColoringProblem(; structure=:symmetric, partition=:column)
problem2 = ColoringProblem(; structure=:nonsymmetric, partition=:column)
Comment thread
samuelsonric marked this conversation as resolved.
Outdated
algorithm = GreedyColoringAlgorithm(
PerfectEliminationOrder(); decompression=:substitution
)

for (n, m) in ((800, 80), (400, 40), (200, 20), (100, 10))
perm = randperm(n)
matrix = permute!(sparse(Symmetric(brand(n, n, m, 0), :L)), perm, perm)
Comment thread
samuelsonric marked this conversation as resolved.
@test ncolors(coloring(matrix, problem1, algorithm)) == 1m + 1
@test ncolors(coloring(matrix, problem2, algorithm)) == 2m + 1
end
end