Skip to content

Commit 93055be

Browse files
authored
[Bridges] fix IndicatorToMILPBridge when z is not binary (#2857)
1 parent 7dd688c commit 93055be

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@ end
188188

189189
MOI.Bridges.needs_final_touch(::IndicatorToMILPBridge) = true
190190

191+
function _is_binary(model::MOI.ModelLike, f::MOI.AbstractScalarFunction)
192+
x = convert(MOI.VariableIndex, f)
193+
return _is_binary(model, x)
194+
end
195+
196+
function _is_binary(model::MOI.ModelLike, x::MOI.VariableIndex)
197+
return MOI.is_valid(
198+
model,
199+
MOI.ConstraintIndex{MOI.VariableIndex,MOI.ZeroOne}(x.value),
200+
)
201+
end
202+
191203
function MOI.Bridges.final_touch(
192204
bridge::IndicatorToMILPBridge{T,F},
193205
model::MOI.ModelLike,
@@ -198,6 +210,10 @@ function MOI.Bridges.final_touch(
198210
ret = MOI.Utilities.get_bounds(model, bounds, fi)
199211
if ret === nothing
200212
throw(MOI.Bridges.BridgeRequiresFiniteDomainError(bridge, fi))
213+
elseif !_is_binary(model, scalars[1])
214+
error(
215+
"Unable to reformulate indicator constraint to a MILP. The indicator variable must be binary.",
216+
)
201217
end
202218
if bridge.slack === nothing
203219
# This is the first time calling final_touch

test/Bridges/Constraint/IndicatorToMILPBridge.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,25 @@ function test_delete_before_final_touch()
301301
return
302302
end
303303

304+
function test_runtests_error_not_binary()
305+
inner = MOI.Utilities.Model{Int}()
306+
model = MOI.Bridges.Constraint.IndicatorToMILP{Int}(inner)
307+
x = MOI.add_variables(model, 2)
308+
MOI.add_constraint(model, x[2], MOI.Interval(0, 4))
309+
c = MOI.add_constraint(
310+
model,
311+
MOI.VectorOfVariables(x),
312+
MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.GreaterThan(2)),
313+
)
314+
@test_throws(
315+
ErrorException(
316+
"Unable to reformulate indicator constraint to a MILP. The indicator variable must be binary.",
317+
),
318+
MOI.Bridges.final_touch(model),
319+
)
320+
return
321+
end
322+
304323
end # module
305324

306325
TestConstraintIndicatorToMILP.runtests()

0 commit comments

Comments
 (0)