/
test_callbacks.jl
121 lines (112 loc) · 3.86 KB
/
test_callbacks.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# Copyright 2017, Iain Dunning, Joey Huchette, Miles Lubin, and contributors
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
module TestCallbacks
using JuMP
using Test
struct DummyCallbackData end
function test_LazyConstraint()
mock = MOI.Utilities.MockOptimizer(
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
)
model = Model(() -> mock)
@variable(model, 0 <= x <= 2.5, Int)
# We attach optimizer here, because when submitting the lazy constraint
# in reality, we will be in `optimize!`, so the optimizer will be
# attached.
MOIU.attach_optimizer(model)
con = @build_constraint(x <= 2)
MOI.submit(model, MOI.LazyConstraint(DummyCallbackData()), con)
@test length(mock.submitted) == 1
c = mock.submitted[MOI.LazyConstraint(DummyCallbackData())]
@test length(c) == 1
@test c[1][1] isa MOI.ScalarAffineFunction{Float64}
@test c[1][1].constant == 0.0
@test length(c[1][1].terms) == 1
@test c[1][1].terms[1].coefficient == 1.0
@test c[1][2] == MOI.LessThan(2.0)
return
end
function test_UserCut()
mock = MOI.Utilities.MockOptimizer(
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
)
model = direct_model(mock)
@variable(model, 0 <= x <= 2.5, Int)
con = @build_constraint(x <= 2)
MOI.submit(model, MOI.UserCut(DummyCallbackData()), con)
@test length(mock.submitted) == 1
c = mock.submitted[MOI.UserCut(DummyCallbackData())]
@test length(c) == 1
@test c[1][1] ≈ moi_function(1.0 * x)
@test c[1][2] == MOI.LessThan(2.0)
return
end
function test_HeuristicSolution()
mock = MOI.Utilities.MockOptimizer(
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
)
model = direct_model(mock)
@variable(model, 0 <= x <= 2.5, Int)
con = @build_constraint(x <= 2)
MOI.submit(model, MOI.HeuristicSolution(DummyCallbackData()), [x], [0.0])
@test length(mock.submitted) == 1
c = mock.submitted[MOI.HeuristicSolution(DummyCallbackData())]
@test length(c) == 1
@test c[1][1] == [index(x)]
@test c[1][2] == [0.0]
# Non-Float64 case
MOI.submit(model, MOI.HeuristicSolution(DummyCallbackData()), [x], [1])
@test length(mock.submitted) == 1
c = mock.submitted[MOI.HeuristicSolution(DummyCallbackData())]
@test length(c) == 2
@test c[2][1] == [index(x)]
@test c[2][2] == [1.0]
return
end
function test_callback_value()
mock = MOI.Utilities.MockOptimizer(
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
)
cb = DummyCallbackData()
model = direct_model(mock)
@variable(model, 0 <= x <= 2.5, Int)
MOIU.set_mock_optimize!(
mock,
mock -> begin
MOI.set(mock, MOI.TerminationStatus(), MOI.OPTIMAL)
MOI.set(mock, MOI.CallbackVariablePrimal(cb), index(x), 1)
end,
)
optimize!(model)
@test callback_value(cb, x) == 1
expr = x + 1
@test callback_value(cb, expr) == 2
quad_expr = expr^2
@test callback_value(cb, quad_expr) == 4
return
end
function test_callback_node_status()
mock = MOI.Utilities.MockOptimizer(
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
)
cb = DummyCallbackData()
model = direct_model(mock)
@variable(model, 0 <= x <= 2.5, Int)
MOIU.set_mock_optimize!(
mock,
mock -> begin
MOI.set(mock, MOI.TerminationStatus(), MOI.OPTIMAL)
MOI.set(
mock,
MOI.CallbackNodeStatus(cb),
MOI.CALLBACK_NODE_STATUS_INTEGER,
)
end,
)
optimize!(model)
@test callback_node_status(cb, model) == MOI.CALLBACK_NODE_STATUS_INTEGER
return
end
end # module