Skip to content

Commit 62390ac

Browse files
committed
Add tests
1 parent 684ee4f commit 62390ac

File tree

2 files changed

+235
-1
lines changed

2 files changed

+235
-1
lines changed

src/Utilities/feasibility_relaxation.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ end
111111
function MOI.supports(
112112
::MOI.ModelLike,
113113
::FeasibilityRelaxation,
114-
::Type{MOI.ConstraintIndex{F,<:MOI.AbstractScalarSet}},
114+
::Type{<:MOI.ConstraintIndex{F,<:MOI.AbstractScalarSet}},
115115
) where {T,F<:Union{MOI.ScalarAffineFunction{T},MOI.ScalarQuadraticFunction{T}}}
116116
return true
117117
end
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# Copyright (c) 2017: Miles Lubin and contributors
2+
# Copyright (c) 2017: Google Inc.
3+
#
4+
# Use of this source code is governed by an MIT-style license that can be found
5+
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
6+
7+
module TestFeasibilityRelaxation
8+
9+
using Test
10+
using MathOptInterface
11+
12+
const MOI = MathOptInterface
13+
14+
function runtests()
15+
for name in names(@__MODULE__; all = true)
16+
if startswith("$(name)", "test_")
17+
@testset "$(name)" begin
18+
getfield(@__MODULE__, name)()
19+
end
20+
end
21+
end
22+
return
23+
end
24+
25+
function _test_roundtrip(src_str, relaxed_str)
26+
model = MOI.Utilities.Model{Float64}()
27+
MOI.Utilities.loadfromstring!(model, src_str)
28+
MOI.set(model, MOI.Utilities.FeasibilityRelaxation())
29+
dest = MOI.Utilities.Model{Float64}()
30+
MOI.Utilities.loadfromstring!(dest, relaxed_str)
31+
MOI.Bridges._test_structural_identical(model, dest)
32+
return
33+
end
34+
35+
function test_relax_bounds()
36+
_test_roundtrip(
37+
"""
38+
variables: x, y
39+
minobjective: x + y
40+
x >= 0.0
41+
y <= 0.0
42+
x in ZeroOne()
43+
y in Integer()
44+
""",
45+
"""
46+
variables: x, y
47+
minobjective: x + y
48+
x >= 0.0
49+
y <= 0.0
50+
x in ZeroOne()
51+
y in Integer()
52+
""",
53+
)
54+
return
55+
end
56+
57+
function test_relax_affine_lessthan()
58+
_test_roundtrip(
59+
"""
60+
variables: x, y
61+
minobjective: x + y
62+
c1: x + y <= 1.0
63+
""",
64+
"""
65+
variables: x, y, a
66+
minobjective: x + y + a
67+
c1: x + y + -1.0 * a <= 1.0
68+
a >= 0.0
69+
""",
70+
)
71+
return
72+
end
73+
74+
function test_relax_affine_lessthan_max()
75+
_test_roundtrip(
76+
"""
77+
variables: x, y
78+
maxobjective: x + y
79+
c1: x + y <= 1.0
80+
""",
81+
"""
82+
variables: x, y, a
83+
maxobjective: x + y + -1.0 * a
84+
c1: x + y + -1.0 * a <= 1.0
85+
a >= 0.0
86+
""",
87+
)
88+
return
89+
end
90+
91+
function test_relax_affine_lessthan_no_objective()
92+
_test_roundtrip(
93+
"""
94+
variables: x, y
95+
c1: x + y <= 1.0
96+
""",
97+
"""
98+
variables: x, y, a
99+
minobjective: 1.0 * a
100+
c1: x + y + -1.0 * a <= 1.0
101+
a >= 0.0
102+
""",
103+
)
104+
return
105+
end
106+
107+
function test_relax_affine_lessthan_quad_objective()
108+
_test_roundtrip(
109+
"""
110+
variables: x, y
111+
maxobjective: 1.0 * x * y
112+
c1: x + y <= 1.0
113+
""",
114+
"""
115+
variables: x, y, a
116+
maxobjective: 1.0 * x * y + -1.0 * a
117+
c1: x + y + -1.0 * a <= 1.0
118+
a >= 0.0
119+
""",
120+
)
121+
return
122+
end
123+
124+
function test_relax_affine_greaterthan()
125+
_test_roundtrip(
126+
"""
127+
variables: x, y
128+
minobjective: x + y
129+
c1: x + y >= 1.0
130+
""",
131+
"""
132+
variables: x, y, a
133+
minobjective: x + y + a
134+
c1: x + y + 1.0 * a >= 1.0
135+
a >= 0.0
136+
""",
137+
)
138+
return
139+
end
140+
141+
function test_relax_affine_equalto()
142+
_test_roundtrip(
143+
"""
144+
variables: x, y
145+
minobjective: x + y
146+
c1: x + y == 1.0
147+
""",
148+
"""
149+
variables: x, y, a, b
150+
minobjective: x + y + a + b
151+
c1: x + y + 1.0 * a + -1.0 * b == 1.0
152+
a >= 0.0
153+
b >= 0.0
154+
""",
155+
)
156+
return
157+
end
158+
159+
function test_relax_affine_interval()
160+
_test_roundtrip(
161+
"""
162+
variables: x, y
163+
minobjective: x + y
164+
c1: x + y in Interval(5.0, 6.0)
165+
""",
166+
"""
167+
variables: x, y, a, b
168+
minobjective: x + y + a + b
169+
c1: x + y + 1.0 * a + -1.0 * b in Interval(5.0, 6.0)
170+
a >= 0.0
171+
b >= 0.0
172+
""",
173+
)
174+
return
175+
end
176+
177+
function test_relax_quadratic_lessthan()
178+
_test_roundtrip(
179+
"""
180+
variables: x, y
181+
maxobjective: x + y
182+
c1: 1.0 * x * x + 2.0 * x * y <= 1.0
183+
""",
184+
"""
185+
variables: x, y, a
186+
maxobjective: x + y + -1.0 * a
187+
c1: 1.0 * x * x + 2.0 * x * y + -1.0 * a <= 1.0
188+
a >= 0.0
189+
""",
190+
)
191+
return
192+
end
193+
194+
function test_relax_quadratic_greaterthanthan()
195+
_test_roundtrip(
196+
"""
197+
variables: x, y
198+
maxobjective: x + y
199+
c1: 1.0 * x * x + 2.0 * x * y >= 1.0
200+
""",
201+
"""
202+
variables: x, y, a
203+
maxobjective: x + y + -1.0 * a
204+
c1: 1.0 * x * x + 2.0 * x * y + 1.0 * a >= 1.0
205+
a >= 0.0
206+
""",
207+
)
208+
return
209+
end
210+
211+
function test_penalties()
212+
model = MOI.Utilities.Model{Float64}()
213+
x = MOI.add_variable(model)
214+
c = MOI.add_constraint(model, 1.0 * x, MOI.EqualTo(2.0))
215+
MOI.set(model, MOI.Utilities.FeasibilityRelaxation(Dict(c => 2.0)))
216+
@test sprint(print, model) === """
217+
Minimize ScalarAffineFunction{Float64}:
218+
0.0 + 2.0 v[2] + 2.0 v[3]
219+
220+
Subject to:
221+
222+
ScalarAffineFunction{Float64}-in-EqualTo{Float64}
223+
0.0 + 1.0 v[1] + 1.0 v[2] - 1.0 v[3] == 2.0
224+
225+
VariableIndex-in-GreaterThan{Float64}
226+
v[2] >= 0.0
227+
v[3] >= 0.0
228+
"""
229+
return
230+
end
231+
232+
end
233+
234+
TestFeasibilityRelaxation.runtests()

0 commit comments

Comments
 (0)