Skip to content

Commit e6c869d

Browse files
committed
Update merge with IIS conflits
1 parent c523cfb commit e6c869d

File tree

2 files changed

+90
-48
lines changed

2 files changed

+90
-48
lines changed

src/MOI_wrapper.jl

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,12 +2348,14 @@ end
23482348
"""
23492349
ConflictStatus()
23502350
2351-
Return an `MOI.TerminationStatusCode` indicating the status of the last computed conflict.
2352-
If a minimal conflict is found, it will return `MOI.OPTIMAL`. If the problem is feasible, it will
2353-
return `MOI.INFEASIBLE`. If `compute_conflict` has not been called yet, it will return
2351+
Return an `MOI.TerminationStatusCode` indicating the status of the last
2352+
computed conflict. If a minimal conflict is found, it will return
2353+
`MOI.OPTIMAL`. If the problem is feasible, it will return `MOI.INFEASIBLE`. If
2354+
`compute_conflict` has not been called yet, it will return
23542355
`MOI.OPTIMIZE_NOT_CALLED`.
23552356
"""
2356-
struct ConflictStatus <: MOI.AbstractModelAttribute end
2357+
struct ConflictStatus <: MOI.AbstractModelAttribute end
2358+
23572359
MOI.is_set_by_optimize(::ConflictStatus) = true
23582360

23592361
function MOI.get(model::Optimizer, ::ConflictStatus)
@@ -2398,45 +2400,103 @@ end
23982400

23992401
"""
24002402
ConstraintConflictStatus()
2401-
A Boolean constraint attribute indicating whether the constraint participates in the last computed conflict.
2403+
2404+
A Boolean constraint attribute indicating whether the constraint participates
2405+
in the last computed conflict.
24022406
"""
24032407
struct ConstraintConflictStatus <: MOI.AbstractConstraintAttribute end
2408+
24042409
MOI.is_set_by_optimize(::ConstraintConflictStatus) = true
24052410

2406-
function MOI.get(model::Optimizer, ::ConstraintConflictStatus, index::MOI.ConstraintIndex{<:MOI.SingleVariable, <:LQOI.LE})
2411+
function MOI.get(
2412+
model::Optimizer, ::ConstraintConflictStatus,
2413+
index::MOI.ConstraintIndex{MOI.SingleVariable, <:MOI.LessThan}
2414+
)
24072415
_ensure_conflict_computed(model)
2408-
return !_is_feasible(model) && Bool(get_intattrelement(model.inner, "IISUB", LQOI.get_column(model, model[index])))
2416+
if _is_feasible(model)
2417+
return false
2418+
end
2419+
return get_intattrelement(model.inner, "IISUB", _info(model, index).column) > 0
24092420
end
24102421

2411-
function MOI.get(model::Optimizer, ::ConstraintConflictStatus, index::MOI.ConstraintIndex{<:MOI.SingleVariable, <:LQOI.GE})
2422+
function MOI.get(
2423+
model::Optimizer, ::ConstraintConflictStatus,
2424+
index::MOI.ConstraintIndex{MOI.SingleVariable, <:MOI.GreaterThan}
2425+
)
24122426
_ensure_conflict_computed(model)
2413-
return !_is_feasible(model) && Bool(get_intattrelement(model.inner, "IISLB", LQOI.get_column(model, model[index])))
2427+
if _is_feasible(model)
2428+
return false
2429+
end
2430+
return get_intattrelement(model.inner, "IISLB", _info(model, index).column) > 0
24142431
end
24152432

2416-
function MOI.get(model::Optimizer, ::ConstraintConflictStatus, index::MOI.ConstraintIndex{<:MOI.SingleVariable, <:Union{LQOI.EQ, LQOI.IV}})
2433+
function MOI.get(
2434+
model::Optimizer, ::ConstraintConflictStatus,
2435+
index::MOI.ConstraintIndex{
2436+
MOI.SingleVariable, <:Union{MOI.EqualTo, MOI.Interval}
2437+
}
2438+
)
24172439
_ensure_conflict_computed(model)
2418-
return !_is_feasible(model) && (
2419-
Bool(get_intattrelement(model.inner, "IISUB", LQOI.get_column(model, model[index]))) || Bool(get_intattrelement(model.inner, "IISLB", model[index])))
2440+
if _is_feasible(model)
2441+
return false
2442+
end
2443+
if get_intattrelement(model.inner, "IISLB", _info(model, index).column) > 0
2444+
return true
2445+
end
2446+
return get_intattrelement(model.inner, "IISUB", _info(model, index).column) > 0
24202447
end
24212448

2422-
function MOI.get(model::Optimizer, ::ConstraintConflictStatus, index::MOI.ConstraintIndex{<:MOI.ScalarAffineFunction, <:Union{LQOI.LE, LQOI.GE, LQOI.EQ}})
2449+
function MOI.get(
2450+
model::Optimizer, ::ConstraintConflictStatus,
2451+
index::MOI.ConstraintIndex{
2452+
MOI.ScalarAffineFunction{Float64},
2453+
<:Union{MOI.LessThan, MOI.GreaterThan, MOI.EqualTo}
2454+
}
2455+
)
24232456
_ensure_conflict_computed(model)
2424-
return !_is_feasible(model) && Bool(get_intattrelement(model.inner, "IISConstr", model[index]))
2457+
if _is_feasible(model)
2458+
return false
2459+
end
2460+
return get_intattrelement(model.inner, "IISConstr", _info(model, index).row) > 0
24252461
end
24262462

2427-
function MOI.get(model::Optimizer, ::ConstraintConflictStatus, index::MOI.ConstraintIndex{<:MOI.ScalarQuadraticFunction, <:Union{LQOI.LE, LQOI.GE}})
2463+
function MOI.get(
2464+
model::Optimizer, ::ConstraintConflictStatus,
2465+
index::MOI.ConstraintIndex{
2466+
MOI.ScalarQuadraticFunction{Float64},
2467+
<:Union{MOI.LessThan, MOI.GreaterThan}
2468+
}
2469+
)
24282470
_ensure_conflict_computed(model)
2429-
return !_is_feasible(model) && Bool(get_intattrelement(model.inner, "IISQConstr", model[index]))
2471+
if _is_feasible(model)
2472+
return false
2473+
end
2474+
return get_intattrelement(model.inner, "IISQConstr", _info(model, index).row) > 0
24302475
end
24312476

2432-
function MOI.supports(::Optimizer, ::ConstraintConflictStatus, ::Type{MOI.ConstraintIndex{<:MOI.SingleVariable, <:LQOI.LinSets}})
2477+
function MOI.supports(
2478+
::Optimizer, ::ConstraintConflictStatus,
2479+
::Type{<:MOI.ConstraintIndex{MOI.SingleVariable, <:SCALAR_SETS}}
2480+
)
24332481
return true
24342482
end
24352483

2436-
function MOI.supports(::Optimizer, ::ConstraintConflictStatus, ::Type{MOI.ConstraintIndex{<:MOI.ScalarAffineFunction, <:Union{LQOI.LE, LQOI.GE, LQOI.EQ}}})
2484+
function MOI.supports(
2485+
::Optimizer, ::ConstraintConflictStatus,
2486+
::Type{<:MOI.ConstraintIndex{
2487+
MOI.ScalarAffineFunction{Float64},
2488+
<:Union{MOI.LessThan, MOI.GreaterThan, MOI.EqualTo}
2489+
}}
2490+
)
24372491
return true
24382492
end
24392493

2440-
function MOI.supports(::Optimizer, ::ConstraintConflictStatus, ::Type{MOI.ConstraintIndex{<:MOI.ScalarQuadraticFunction, <:Union{LQOI.LE, LQOI.GE}}})
2494+
function MOI.supports(
2495+
::Optimizer, ::ConstraintConflictStatus,
2496+
::Type{<:MOI.ConstraintIndex{
2497+
MOI.ScalarQuadraticFunction{Float64},
2498+
<:Union{MOI.LessThan, MOI.GreaterThan}
2499+
}}
2500+
)
24412501
return true
24422502
end

test/MOI_wrapper.jl

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ end
314314

315315
@testset "Conflict refiner" begin
316316
@testset "Variable bounds (SingleVariable and LessThan/GreaterThan)" begin
317-
model = Gurobi.Optimizer()
317+
model = Gurobi.Optimizer(GUROBI_ENV, OutputFlag=0)
318318
x = MOI.add_variable(model)
319319
c1 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.GreaterThan(2.0))
320320
c2 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.LessThan(1.0))
@@ -332,7 +332,7 @@ end
332332
end
333333

334334
@testset "Variable bounds (ScalarAffine)" begin
335-
model = Gurobi.Optimizer()
335+
model = Gurobi.Optimizer(GUROBI_ENV, OutputFlag=0)
336336
x = MOI.add_variable(model)
337337
c1 = MOI.add_constraint(model, MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0], [x]), 0.0), MOI.GreaterThan(2.0))
338338
c2 = MOI.add_constraint(model, MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0], [x]), 0.0), MOI.LessThan(1.0))
@@ -348,29 +348,12 @@ end
348348
@test MOI.get(model, Gurobi.ConstraintConflictStatus(), c2) == true
349349
end
350350

351-
@testset "Variable fixing (SingleVariable and EqualTo)" begin
352-
model = Gurobi.Optimizer()
353-
x = MOI.add_variable(model)
354-
c1 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.EqualTo(1.0))
355-
c2 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.GreaterThan(2.0))
356-
357-
# Getting the results before the conflict refiner has been called must return an error.
358-
@test MOI.get(model, Gurobi.ConflictStatus()) == MOI.OPTIMIZE_NOT_CALLED
359-
@test_throws ErrorException MOI.get(model, Gurobi.ConstraintConflictStatus(), c1)
360-
361-
# Once it's called, no problem.
362-
Gurobi.compute_conflict(model)
363-
@test MOI.get(model, Gurobi.ConflictStatus()) == MOI.OPTIMAL
364-
@test MOI.get(model, Gurobi.ConstraintConflictStatus(), c1) == true
365-
@test MOI.get(model, Gurobi.ConstraintConflictStatus(), c2) == true
366-
end
367-
368-
@testset "Variable bounds (SingleVariable and Interval)" begin
369-
model = Gurobi.Optimizer()
351+
@testset "Variable bounds (Invali Interval)" begin
352+
model = Gurobi.Optimizer(GUROBI_ENV, OutputFlag=0)
370353
x = MOI.add_variable(model)
371-
c1 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.Interval(1.0, 3.0))
372-
c2 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.LessThan(0.0))
373-
354+
c1 = MOI.add_constraint(
355+
model, MOI.SingleVariable(x), MOI.Interval(1.0, 0.0)
356+
)
374357
# Getting the results before the conflict refiner has been called must return an error.
375358
@test MOI.get(model, Gurobi.ConflictStatus()) == MOI.OPTIMIZE_NOT_CALLED
376359
@test_throws ErrorException MOI.get(model, Gurobi.ConstraintConflictStatus(), c1)
@@ -379,11 +362,10 @@ end
379362
Gurobi.compute_conflict(model)
380363
@test MOI.get(model, Gurobi.ConflictStatus()) == MOI.OPTIMAL
381364
@test MOI.get(model, Gurobi.ConstraintConflictStatus(), c1) == true
382-
@test MOI.get(model, Gurobi.ConstraintConflictStatus(), c2) == true
383365
end
384366

385367
@testset "Two conflicting constraints (GreaterThan, LessThan)" begin
386-
model = Gurobi.Optimizer()
368+
model = Gurobi.Optimizer(GUROBI_ENV, OutputFlag=0)
387369
x = MOI.add_variable(model)
388370
y = MOI.add_variable(model)
389371
b1 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.GreaterThan(0.0))
@@ -407,7 +389,7 @@ end
407389
end
408390

409391
@testset "Two conflicting constraints (EqualTo)" begin
410-
model = Gurobi.Optimizer()
392+
model = Gurobi.Optimizer(GUROBI_ENV, OutputFlag=0)
411393
x = MOI.add_variable(model)
412394
y = MOI.add_variable(model)
413395
b1 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.GreaterThan(0.0))
@@ -431,7 +413,7 @@ end
431413
end
432414

433415
@testset "Variables outside conflict" begin
434-
model = Gurobi.Optimizer()
416+
model = Gurobi.Optimizer(GUROBI_ENV, OutputFlag=0)
435417
x = MOI.add_variable(model)
436418
y = MOI.add_variable(model)
437419
z = MOI.add_variable(model)
@@ -458,7 +440,7 @@ end
458440
end
459441

460442
@testset "No conflict" begin
461-
model = Gurobi.Optimizer()
443+
model = Gurobi.Optimizer(GUROBI_ENV, OutputFlag=0)
462444
x = MOI.add_variable(model)
463445
c1 = MOI.add_constraint(model, MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0], [x]), 0.0), MOI.GreaterThan(1.0))
464446
c2 = MOI.add_constraint(model, MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0], [x]), 0.0), MOI.LessThan(2.0))

0 commit comments

Comments
 (0)