Skip to content

Commit fae47b1

Browse files
committed
add Hull tests/bug fix
1 parent c788b10 commit fae47b1

File tree

2 files changed

+65
-15
lines changed

2 files changed

+65
-15
lines changed

src/hull.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ function _disaggregate_nl_expression(model::Model, c::Number, ::VariableRef, met
105105
end
106106
# variable in NonlinearExpr
107107
function _disaggregate_nl_expression(model::Model, vref::VariableRef, bvref::VariableRef, method::_Hull)
108+
ϵ = method.value
108109
if is_binary(vref) || !haskey(method.disjunct_variables, (vref, bvref)) #keep any binary variables or nested disaggregated variables unchanged
109-
return vref
110+
dvref = vref
110111
else #replace with disaggregated form
111-
ϵ = method.value
112112
dvref = method.disjunct_variables[vref, bvref]
113-
return dvref / ((1-ϵ)*bvref+ϵ)
114113
end
114+
return dvref / ((1-ϵ)*bvref+ϵ)
115115
end
116116
# affine expression in NonlinearExpr
117117
function _disaggregate_nl_expression(model::Model, aff::AffExpr, bvref::VariableRef, method::_Hull)
@@ -123,7 +123,7 @@ function _disaggregate_nl_expression(model::Model, aff::AffExpr, bvref::Variable
123123
else #replace other vars with disaggregated form
124124
dvref = method.disjunct_variables[vref, bvref]
125125
end
126-
new_expr += coeff * dvref / ((1-ϵ)*bvref+ϵ)
126+
new_expr += coeff * dvref / ((1-ϵ)*bvref+ϵ)
127127
end
128128
return new_expr
129129
end

test/constraints/hull.jl

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,22 @@ function test_aggregate_variable()
7777
@test refcons[1].set == MOI.EqualTo(0.)
7878
end
7979

80+
function test_disaggregate_expression_var()
81+
model = GDPModel()
82+
@variable(model, 10 <= x <= 100)
83+
@variable(model, z, Logical)
84+
DP._reformulate_logical_variables(model)
85+
bvrefs = DP._indicator_to_binary(model)
86+
87+
vrefs = Set([x])
88+
method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs)
89+
DP._disaggregate_variables(model, z, vrefs, method)
90+
91+
refexpr = DP._disaggregate_expression(model, x, bvrefs[z], method)
92+
x_z = variable_by_name(model, "x_z")
93+
@test refexpr == x_z
94+
end
95+
8096
function test_disaggregate_expression_var_binary()
8197
model = GDPModel()
8298
@variable(model, x, Bin)
@@ -93,7 +109,7 @@ function test_disaggregate_expression_var_binary()
93109
@test refexpr == x
94110
end
95111

96-
function test_disaggregate_expression_var()
112+
function test_disaggregate_expression_affine()
97113
model = GDPModel()
98114
@variable(model, 10 <= x <= 100)
99115
@variable(model, z, Logical)
@@ -104,26 +120,28 @@ function test_disaggregate_expression_var()
104120
method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs)
105121
DP._disaggregate_variables(model, z, vrefs, method)
106122

107-
refexpr = DP._disaggregate_expression(model, x, bvrefs[z], method)
123+
refexpr = DP._disaggregate_expression(model, 2x + 1, bvrefs[z], method)
108124
x_z = variable_by_name(model, "x_z")
109-
@test refexpr == x_z
125+
zbin = variable_by_name(model, "z")
126+
@test refexpr == 2x_z + 1zbin
110127
end
111128

112-
function test_disaggregate_expression_affine()
129+
function test_disaggregate_expression_affine_mip()
113130
model = GDPModel()
114131
@variable(model, 10 <= x <= 100)
132+
@variable(model, y, Bin)
115133
@variable(model, z, Logical)
116134
DP._reformulate_logical_variables(model)
117135
bvrefs = DP._indicator_to_binary(model)
118136

119-
vrefs = Set([x])
120-
method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.))), vrefs)
137+
vrefs = Set([x, y])
138+
method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.), y => (0., 1.))), vrefs)
121139
DP._disaggregate_variables(model, z, vrefs, method)
122140

123-
refexpr = DP._disaggregate_expression(model, 2x + 1, bvrefs[z], method)
141+
refexpr = DP._disaggregate_expression(model, 2x + y + 1, bvrefs[z], method)
124142
x_z = variable_by_name(model, "x_z")
125143
zbin = variable_by_name(model, "z")
126-
@test refexpr == 2x_z + 1zbin
144+
@test refexpr == 2x_z + y + 1zbin
127145
end
128146

129147
function test_disaggregate_expression_quadratic()
@@ -176,7 +194,10 @@ function test_disaggregate_nl_expression_var_binary()
176194
DP._disaggregate_variables(model, z, vrefs, method)
177195

178196
refexpr = DP._disaggregate_nl_expression(model, x, bvrefs[z], method)
179-
@test refexpr == x
197+
ϵ = method.value
198+
@test refexpr.head == :/
199+
@test x in refexpr.args
200+
@test (1-ϵ)*bvrefs[z]+ϵ in refexpr.args
180201
end
181202

182203
function test_disaggregate_nl_expression_var()
@@ -222,6 +243,33 @@ function test_disaggregate_nl_expression_aff()
222243
@test (1-ϵ)*zbin+ϵ in arg2.args
223244
end
224245

246+
function test_disaggregate_nl_expression_aff_mip()
247+
model = GDPModel()
248+
@variable(model, 10 <= x <= 100)
249+
@variable(model, y, Bin)
250+
@variable(model, z, Logical)
251+
DP._reformulate_logical_variables(model)
252+
bvrefs = DP._indicator_to_binary(model)
253+
254+
vrefs = Set([x,y])
255+
method = DP._Hull(Hull(1e-3, Dict(x => (0., 100.), y => (0., 1.))), vrefs)
256+
DP._disaggregate_variables(model, z, vrefs, method)
257+
258+
refexpr = DP._disaggregate_nl_expression(model, 2x + y + 1, bvrefs[z], method)
259+
flatten!(refexpr)
260+
x_z = variable_by_name(model, "x_z")
261+
zbin = variable_by_name(model, "z")
262+
ϵ = method.value
263+
@test refexpr.head == :+
264+
@test 1 in refexpr.args
265+
args2 = setdiff(refexpr.args, [1])
266+
for arg in args2
267+
@test arg.head == :/
268+
@test 2x_z in arg.args || 1y in arg.args
269+
@test (1-ϵ)*zbin+ϵ in arg.args
270+
end
271+
end
272+
225273
function test_disaggregate_nl_expression_quad()
226274
model = GDPModel()
227275
@variable(model, 10 <= x <= 100)
@@ -596,14 +644,16 @@ end
596644
test_query_variable_bounds_error2()
597645
test_disaggregate_variables()
598646
test_aggregate_variable()
599-
test_disaggregate_expression_var_binary()
600647
test_disaggregate_expression_var()
648+
test_disaggregate_expression_var_binary()
601649
test_disaggregate_expression_affine()
650+
test_disaggregate_expression_affine_mip()
602651
test_disaggregate_expression_quadratic()
603652
test_disaggregate_nl_expression_c()
604-
test_disaggregate_nl_expression_var_binary()
605653
test_disaggregate_nl_expression_var()
654+
test_disaggregate_nl_expression_var_binary()
606655
test_disaggregate_nl_expression_aff()
656+
test_disaggregate_nl_expression_aff_mip()
607657
test_disaggregate_nl_expression_quad()
608658
test_disaggregate_nl_expession()
609659
for s in (MOI.LessThan, MOI.GreaterThan, MOI.EqualTo)

0 commit comments

Comments
 (0)