Skip to content

Commit 3a46924

Browse files
authored
use MOI for benchmark tests for better comparison (#59)
1 parent a458ef1 commit 3a46924

File tree

5 files changed

+92
-36
lines changed

5 files changed

+92
-36
lines changed

benchmark/killer_sudoku/cs.jl

+26-14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
using JuMP
2-
using ConstraintSolver
3-
using JSON
1+
using ConstraintSolver, MathOptInterface, JSON
42

5-
CS = ConstraintSolver
3+
if !@isdefined CS
4+
const CS = ConstraintSolver
5+
end
6+
const MOI = MathOptInterface
7+
const MOIU = MOI.Utilities
68
include("../../test/sudoku_fcts.jl")
79

810
function parseJSON(json_sums)
@@ -23,35 +25,45 @@ function solve_all(filenames; benchmark=false, single_times=true)
2325
for (i,filename) in enumerate(filenames)
2426
sums = parseJSON(JSON.parsefile("data/$(filename)"))
2527

26-
m = Model(with_optimizer(CS.Optimizer))
27-
@variable(m, 1 <= x[1:9,1:9] <= 9, Int)
28+
m = CS.Optimizer()
29+
30+
x = [[MOI.add_constrained_variable(m, MOI.Integer()) for i=1:9] for j=1:9]
31+
for r=1:9, c=1:9
32+
MOI.add_constraint(m, x[r][c][1], MOI.GreaterThan(1.0))
33+
MOI.add_constraint(m, x[r][c][1], MOI.LessThan(9.0))
34+
end
2835

2936
for s in sums
30-
@constraint(m, sum([x[ind...] for ind in s.indices]) == s.result)
37+
saf = MOI.ScalarAffineFunction{Float64}([MOI.ScalarAffineTerm(1.0, x[ind[1]][ind[2]][1]) for ind in s.indices], 0.0)
38+
MOI.add_constraint(m, saf, MOI.EqualTo(convert(Float64,s.result)))
3139
# @constraint(m, [x[ind...] for ind in s.indices] in CS.AllDifferentSet(length(s.indices)))
3240
end
3341

3442
# sudoku constraints
35-
jump_add_sudoku_constr!(m, x)
43+
moi_add_sudoku_constr!(m, x)
3644

3745
if single_times
3846
GC.enable(false)
3947
t = time()
40-
optimize!(m)
41-
status = JuMP.termination_status(m)
48+
MOI.optimize!(m)
49+
status = MOI.get(m, MOI.TerminationStatus())
4250
t = time()-t
4351
GC.enable(true)
4452
println(i-1,", ", t)
4553
else
4654
GC.enable(false)
47-
optimize!(m)
48-
status = JuMP.termination_status(m)
55+
MOI.optimize!(m)
56+
status = MOI.get(m, MOI.TerminationStatus())
4957
GC.enable(true)
5058
end
5159
if !benchmark
52-
@show JuMP.backend(m).optimizer.model.inner.info
60+
@show m.inner.info
5361
println("Status: ", status)
54-
@assert jump_fulfills_sudoku_constr(JuMP.value.(x))
62+
solution = zeros(Int, 9, 9)
63+
for r=1:9
64+
solution[r,:] = [MOI.get(m, MOI.VariablePrimal(), x[r][c][1]) for c=1:9]
65+
end
66+
@assert jump_fulfills_sudoku_constr(solution)
5567
end
5668
com = nothing
5769
GC.gc()

benchmark/sudoku/cs.jl

+25-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
using ConstraintSolver, JuMP
1+
using ConstraintSolver, MathOptInterface
22

3-
CS = ConstraintSolver
3+
const CS = ConstraintSolver
4+
const MOI = MathOptInterface
5+
const MOIU = MOI.Utilities
46
include("../../test/sudoku_fcts.jl")
57

68
function from_file(filename, sep='\n')
@@ -22,35 +24,46 @@ function solve_all(grids; benchmark=false, single_times=true)
2224
ct = time()
2325
grids = grids
2426
for (i,grid) in enumerate(grids)
25-
m = Model(with_optimizer(CS.Optimizer))
26-
@variable(m, 1 <= x[1:9,1:9] <= 9, Int)
27+
m = CS.Optimizer()
28+
29+
x = [[MOI.add_constrained_variable(m, MOI.Integer()) for i=1:9] for j=1:9]
30+
for r=1:9, c=1:9
31+
MOI.add_constraint(m, x[r][c][1], MOI.GreaterThan(1.0))
32+
MOI.add_constraint(m, x[r][c][1], MOI.LessThan(9.0))
33+
end
34+
2735
# set variables
2836
for r=1:9, c=1:9
2937
if grid[r,c] != 0
30-
@constraint(m, x[r,c] == grid[r,c])
38+
sat = [MOI.ScalarAffineTerm(1.0, x[r][c][1])]
39+
MOI.add_constraint(m, MOI.ScalarAffineFunction{Float64}(sat, 0.0), MOI.EqualTo(convert(Float64,grid[r,c])))
3140
end
3241
end
3342
# sudoku constraints
34-
jump_add_sudoku_constr!(m, x)
43+
moi_add_sudoku_constr!(m, x)
3544

3645
if single_times
3746
GC.enable(false)
3847
t = time()
39-
optimize!(m)
40-
status = JuMP.termination_status(m)
48+
MOI.optimize!(m)
49+
status = MOI.get(m, MOI.TerminationStatus())
4150
t = time()-t
4251
GC.enable(true)
4352
println(i-1,", ", t)
4453
else
4554
GC.enable(false)
46-
optimize!(m)
47-
status = JuMP.termination_status(m)
55+
MOI.optimize!(m)
56+
status = MOI.get(m, MOI.TerminationStatus())
4857
GC.enable(true)
4958
end
5059
if !benchmark
51-
@show JuMP.backend(m).optimizer.model.inner.info
60+
@show m.inner.info
5261
println("Status: ", status)
53-
@assert jump_fulfills_sudoku_constr(JuMP.value.(x))
62+
solution = zeros(Int, 9, 9)
63+
for r=1:9
64+
solution[r,:] = [MOI.get(m, MOI.VariablePrimal(), x[r][c][1]) for c=1:9]
65+
end
66+
@assert jump_fulfills_sudoku_constr(solution)
5467
end
5568
end
5669
println("")

test/runtests.jl

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ using MathOptInterface, JuMP
55

66
const MOI = MathOptInterface
77
const CS = ConstraintSolver
8+
const MOIU = MOI.Utilities
89

910
include("fct_tests.jl")
1011
include("moi.jl")

test/sudoku_fcts.jl

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using ConstraintSolver
2-
CS = ConstraintSolver
31

42
function sudokus_from_file(filename, sep='\n')
53
s = open(filename) do file
@@ -61,6 +59,26 @@ function jump_add_sudoku_constr!(m, x)
6159
end
6260
end
6361

62+
function moi_add_sudoku_constr!(m, x)
63+
for r = 1:9
64+
MOI.add_constraint(m, MOI.VectorOfVariables([x[r][c][1] for c =1:9]), CS.AllDifferentSet(9))
65+
end
66+
for c = 1:9
67+
MOI.add_constraint(m, MOI.VectorOfVariables([x[r][c][1] for r =1:9]), CS.AllDifferentSet(9))
68+
end
69+
variables = [MOI.VariableIndex(0) for _ = 1:9]
70+
for br=0:2
71+
for bc=0:2
72+
variables_i = 1
73+
for i=br*3+1:(br+1)*3, j=bc*3+1:(bc+1)*3
74+
variables[variables_i] = x[i][j][1]
75+
variables_i += 1
76+
end
77+
MOI.add_constraint(m, variables, CS.AllDifferentSet(9))
78+
end
79+
end
80+
end
81+
6482
function jump_fulfills_sudoku_constr(vals)
6583
for r = 1:9
6684
!allunique(vals[r,:]) && return false

test/sudoku_tests.jl

+20-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@testset "Sudoku" begin
22

3-
@testset "Sudoku from opensourc.es" begin
3+
@testset "Sudoku from opensourc.es using MOI" begin
44
grid = [0 2 1 0 7 9 0 8 5;
55
0 4 5 3 1 0 0 0 9;
66
0 7 0 0 4 0 0 1 0;
@@ -11,20 +11,32 @@
1111
0 9 4 0 0 7 8 0 0;
1212
2 0 0 5 0 0 0 4 0]
1313

14-
m = Model(with_optimizer(CS.Optimizer))
15-
@variable(m, 1 <= x[1:9,1:9] <= 9, Int)
14+
m = CS.Optimizer()
15+
16+
x = [[MOI.add_constrained_variable(m, MOI.Integer()) for i=1:9] for j=1:9]
17+
for r=1:9, c=1:9
18+
MOI.add_constraint(m, x[r][c][1], MOI.GreaterThan(1.0))
19+
MOI.add_constraint(m, x[r][c][1], MOI.LessThan(9.0))
20+
end
21+
1622
# set variables
1723
for r=1:9, c=1:9
1824
if grid[r,c] != 0
19-
@constraint(m, x[r,c] == grid[r,c])
25+
sat = [MOI.ScalarAffineTerm(1.0, x[r][c][1])]
26+
MOI.add_constraint(m, MOI.ScalarAffineFunction{Float64}(sat, 0.0), MOI.EqualTo(convert(Float64,grid[r,c])))
2027
end
2128
end
29+
2230
# sudoku constraints
23-
jump_add_sudoku_constr!(m, x)
31+
moi_add_sudoku_constr!(m, x)
2432

25-
optimize!(m)
26-
@test JuMP.termination_status(m) == MOI.OPTIMAL
27-
@test jump_fulfills_sudoku_constr(JuMP.value.(x))
33+
MOI.optimize!(m)
34+
@test MOI.get(m, MOI.TerminationStatus()) == MOI.OPTIMAL
35+
solution = zeros(Int, 9, 9)
36+
for r=1:9
37+
solution[r,:] = [MOI.get(m, MOI.VariablePrimal(), x[r][c][1]) for c=1:9]
38+
end
39+
@test jump_fulfills_sudoku_constr(solution)
2840
end
2941

3042

0 commit comments

Comments
 (0)