@@ -3,36 +3,55 @@ module SparseMatrixColoringsJuMPExt
33using ADTypes: ADTypes
44using 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
1316import MathOptInterface as MOI
1417using SparseMatrixColorings:
1518 BipartiteGraph, OptimalColoringAlgorithm, nb_vertices, neighbors, pattern, vertices
1619
1720function 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
4665
4766function 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+ )
5071end
5172
5273function 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+ )
5578end
5679
5780end
0 commit comments