Skip to content

Commit

Permalink
Add support for ConstraintConflictStatus with SOS constraints (#603)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Jan 15, 2025
1 parent bd360c1 commit 7b7daf5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
18 changes: 17 additions & 1 deletion src/MOI_wrapper/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3970,7 +3970,7 @@ function _ensure_conflict_computed(model::Optimizer)
end

function _is_feasible(model::Optimizer)
return MOI.get(model, ConflictStatus()) == GRB_INFEASIBLE
return MOI.get(model, ConflictStatus()) == GRB_ERROR_IIS_NOT_INFEASIBLE
end

"""
Expand Down Expand Up @@ -4102,6 +4102,22 @@ function MOI.get(
return p[] > 0 ? MOI.IN_CONFLICT : MOI.NOT_IN_CONFLICT
end

function MOI.get(
model::Optimizer,
::MOI.ConstraintConflictStatus,
index::MOI.ConstraintIndex{MOI.VectorOfVariables,S},
) where {S<:Union{MOI.SOS1,MOI.SOS2}}
_ensure_conflict_computed(model)
if _is_feasible(model)
return MOI.NOT_IN_CONFLICT
end
p = Ref{Cint}(0)
row = Cint(_info(model, index).row - 1)
ret = GRBgetintattrelement(model, "IISSOS", row, p)
_check_ret(model, ret)
return p[] > 0 ? MOI.IN_CONFLICT : MOI.NOT_IN_CONFLICT
end

function MOI.get(
model::Optimizer,
::MOI.ConstraintConflictStatus,
Expand Down
46 changes: 46 additions & 0 deletions test/MOI/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1527,6 +1527,52 @@ function test_Env()
return
end

function test_SOS1_no_conflict()
model = Gurobi.Optimizer(GRB_ENV)
MOI.set(model, MOI.Silent(), true)
x = MOI.add_variables(model, 2)
set = MOI.SOS1([1.0, 2.0])
c1 = MOI.add_constraint(model, MOI.VectorOfVariables(x), set)
MOI.optimize!(model)
MOI.compute_conflict!(model)
@test MOI.get(model, MOI.ConstraintConflictStatus(), c1) ==
MOI.NOT_IN_CONFLICT
return
end

function test_SOS1_in_conflict()
model = Gurobi.Optimizer(GRB_ENV)
MOI.set(model, MOI.Silent(), true)
x = MOI.add_variables(model, 2)
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
MOI.add_constraint.(model, x, MOI.LessThan(1.0))
set = MOI.SOS1([1.0, 2.0])
c1 = MOI.add_constraint(model, MOI.VectorOfVariables(x), set)
c2 = MOI.add_constraint(model, 1.0 * x[1] + 1.0 * x[2], MOI.EqualTo(2.0))
MOI.optimize!(model)
MOI.compute_conflict!(model)
@test MOI.get(model, MOI.ConstraintConflictStatus(), c1) == MOI.IN_CONFLICT
@test MOI.get(model, MOI.ConstraintConflictStatus(), c2) == MOI.IN_CONFLICT
return
end

function test_SOS2_not_in_conflict()
model = Gurobi.Optimizer(GRB_ENV)
MOI.set(model, MOI.Silent(), true)
x = MOI.add_variables(model, 3)
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
set = MOI.SOS2([1.0, 2.0, 3.0])
c1 = MOI.add_constraint(model, MOI.VectorOfVariables(x), set)
f = sum(1.0 * x[i] for i in 1:3)
c2 = MOI.add_constraint(model, f, MOI.EqualTo(-1.0))
MOI.optimize!(model)
MOI.compute_conflict!(model)
@test MOI.get(model, MOI.ConstraintConflictStatus(), c1) ==
MOI.NOT_IN_CONFLICT
@test MOI.get(model, MOI.ConstraintConflictStatus(), c2) == MOI.IN_CONFLICT
return
end

end # TestMOIWrapper

TestMOIWrapper.runtests()

0 comments on commit 7b7daf5

Please sign in to comment.