Skip to content

Commit 6ce99ff

Browse files
committed
Better comments
1 parent 4ca6507 commit 6ce99ff

3 files changed

Lines changed: 49 additions & 10 deletions

File tree

ext/SparseMatrixColoringsJuMPExt.jl

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,55 @@ module SparseMatrixColoringsJuMPExt
33
using ADTypes: ADTypes
44
using JuMP:
55
Model,
6-
assert_is_solved_and_feasible,
6+
is_solved_and_feasible,
77
optimize!,
8+
primal_status,
89
set_silent,
10+
set_start_value,
911
value,
1012
@variable,
1113
@constraint,
1214
@objective
15+
using JuMP
1316
import MathOptInterface as MOI
1417
using SparseMatrixColorings:
1518
BipartiteGraph, OptimalColoringAlgorithm, nb_vertices, neighbors, pattern, vertices
1619

1720
function optimal_distance2_coloring(
18-
bg::BipartiteGraph, ::Val{side}, optimizer::O; silent::Bool=true
21+
bg::BipartiteGraph,
22+
::Val{side},
23+
optimizer::O;
24+
silent::Bool=true,
25+
assert_solved::Bool=true,
1926
) where {side,O}
2027
other_side = 3 - side
2128
n = nb_vertices(bg, Val(side))
2229
model = Model(optimizer)
2330
silent && set_silent(model)
24-
@variable(model, 1 <= color[i = 1:n] <= i, Int)
31+
# one variable per vertex to color, removing some renumbering symmetries
32+
@variable(model, 1 <= color[i=1:n] <= i, Int)
33+
# one variable to count the number of distinct colors
2534
@variable(model, ncolors, Int)
2635
@constraint(model, [ncolors; color] in MOI.CountDistinct(n + 1))
36+
# distance-2 coloring: neighbors of the same vertex must have distinct colors
2737
for i in vertices(bg, Val(other_side))
2838
neigh = neighbors(bg, Val(other_side), i)
2939
@constraint(model, color[neigh] in MOI.AllDifferent(length(neigh)))
3040
end
41+
# minimize the number of distinct colors (can't use maximum because they are not necessarily numbered contiguously)
3142
@objective(model, Min, ncolors)
43+
# actual solving step where time is spent
3244
optimize!(model)
33-
assert_is_solved_and_feasible(model)
45+
if assert_solved
46+
# assert feasibility and optimality
47+
@assert is_solved_and_feasible(model)
48+
else
49+
# only assert feasibility
50+
@assert primal_status(model) == MOI.FEASIBLE_POINT
51+
end
52+
# native solver solutions are floating point numbers
3453
color_int = round.(Int, value.(color))
35-
# remap to 1:cmax
54+
# remap to 1:cmax in case they are not contiguous
3655
true_ncolors = 0
3756
remap = fill(0, maximum(color_int))
3857
for c in color_int
@@ -46,12 +65,16 @@ end
4665

4766
function ADTypes.column_coloring(A::AbstractMatrix, algo::OptimalColoringAlgorithm)
4867
bg = BipartiteGraph(A)
49-
return optimal_distance2_coloring(bg, Val(2), algo.optimizer; algo.silent)
68+
return optimal_distance2_coloring(
69+
bg, Val(2), algo.optimizer; algo.silent, algo.assert_solved
70+
)
5071
end
5172

5273
function ADTypes.row_coloring(A::AbstractMatrix, algo::OptimalColoringAlgorithm)
5374
bg = BipartiteGraph(A)
54-
return optimal_distance2_coloring(bg, Val(1), algo.optimizer; algo.silent)
75+
return optimal_distance2_coloring(
76+
bg, Val(1), algo.optimizer; algo.silent, algo.assert_solved
77+
)
5578
end
5679

5780
end

src/optimal.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,23 @@ Coloring algorithm that relies on mathematical programming with [JuMP](https://j
1111
1212
# Constructor
1313
14-
OptimalColoringAlgorithm(optimizer; silent::Bool=true)
14+
OptimalColoringAlgorithm(optimizer; silent::Bool=true, assert_solved::Bool=true)
1515
1616
The `optimizer` argument can be any JuMP-compatible optimizer.
1717
However, the problem formulation is best suited to CP-SAT optimizers like [MiniZinc](https://github.com/jump-dev/MiniZinc.jl).
1818
You can use [`optimizer_with_attributes`](https://jump.dev/JuMP.jl/stable/api/JuMP/#optimizer_with_attributes) to set solver-specific parameters.
19+
20+
# Keyword arguments
21+
22+
- `silent`: whether to suppress solver output
23+
- `assert_solved`: whether to check that the solver found an optimal solution (as opposed to running out of time for example)
1924
"""
2025
struct OptimalColoringAlgorithm{O} <: ADTypes.AbstractColoringAlgorithm
2126
optimizer::O
2227
silent::Bool
28+
assert_solved::Bool
2329
end
2430

25-
function OptimalColoringAlgorithm(optimizer; silent::Bool=true)
26-
return OptimalColoringAlgorithm(optimizer, silent)
31+
function OptimalColoringAlgorithm(optimizer; silent::Bool=true, assert_solved::Bool=true)
32+
return OptimalColoringAlgorithm(optimizer, silent, assert_solved)
2733
end

test/optimal.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,13 @@ end
3434
@test ncolors(result) >= ncolors(optresult)
3535
end
3636
end
37+
38+
@testset "Too big" begin
39+
A = sprand(rng, Bool, 100, 100, 0.1)
40+
optalgo_timelimit = OptimalColoringAlgorithm(
41+
optimizer_with_attributes(HiGHS.Optimizer, "time_limit" => 10.0); # 1 second
42+
silent=false,
43+
assert_solved=false,
44+
)
45+
@test_throws AssertionError coloring(A, ColoringProblem(), optalgo_timelimit)
46+
end

0 commit comments

Comments
 (0)