Skip to content

Commit a55d81b

Browse files
authored
Update to MathOptIIS@0.2 (#333)
1 parent 57bc70b commit a55d81b

3 files changed

Lines changed: 104 additions & 26 deletions

File tree

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1414
[compat]
1515
HiGHS_jll = "=1.13.1"
1616
LinearAlgebra = "1"
17-
MathOptIIS = "0.1.0"
17+
MathOptIIS = "0.2"
1818
MathOptInterface = "1.34"
1919
OpenBLAS32_jll = "0.3.24"
2020
ParallelTestRunner = "2.4.2"

src/MOI_wrapper.jl

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,6 +3374,41 @@ function MOI.write_to_file(model::Optimizer, filename::String)
33743374
return
33753375
end
33763376

3377+
function MOI.compute_conflict!(model::Optimizer)
3378+
solver = MathOptIIS.Optimizer()
3379+
MOI.set(solver, MathOptIIS.InfeasibleModel(), model)
3380+
MOI.set(solver, MathOptIIS.InnerOptimizer(), Optimizer)
3381+
MOI.set(solver, MOI.Silent(), MOI.get(model, MOI.Silent()))
3382+
if (time_limit = MOI.get(model, MOI.TimeLimitSec())) !== nothing
3383+
MOI.set(solver, MOI.TimeLimitSec(), time_limit)
3384+
end
3385+
MOI.compute_conflict!(solver)
3386+
model.conflict_solver = solver
3387+
return
3388+
end
3389+
3390+
function MOI.get(optimizer::Optimizer, attr::MOI.ConflictStatus)
3391+
if optimizer.conflict_solver === nothing
3392+
return MOI.COMPUTE_CONFLICT_NOT_CALLED
3393+
end
3394+
return MOI.get(optimizer.conflict_solver, attr)
3395+
end
3396+
3397+
function MOI.get(optimizer::Optimizer, attr::MOI.ConflictCount)
3398+
if optimizer.conflict_solver === nothing
3399+
return 0
3400+
end
3401+
return MOI.get(optimizer.conflict_solver, attr)
3402+
end
3403+
3404+
function MOI.get(
3405+
optimizer::Optimizer,
3406+
attr::MOI.ConstraintConflictStatus,
3407+
con::MOI.ConstraintIndex,
3408+
)
3409+
return MOI.get(optimizer.conflict_solver, attr, con)
3410+
end
3411+
33773412
# These enums are deprecated. Use the `kHighsXXX` constants defined in
33783413
# libhighs.jl instead.
33793414

@@ -3402,28 +3437,3 @@ end
34023437
@enum(HighsObjSense, kMinimize = 1, kMaximize = -1)
34033438
@enum(HighsVartype, kContinuous = 0, kInteger = 1, kImplicitInteger = 2)
34043439
@enum(HighsStatus, HighsStatuskError = -1, HighsStatuskOk, HighsStatuskWarning)
3405-
3406-
function MOI.compute_conflict!(model::Optimizer)
3407-
solver = MathOptIIS.Optimizer()
3408-
MOI.set(solver, MathOptIIS.InfeasibleModel(), model)
3409-
MOI.set(solver, MathOptIIS.InnerOptimizer(), Optimizer)
3410-
MOI.set(solver, MOI.Silent(), MOI.get(model, MOI.Silent()))
3411-
MOI.compute_conflict!(solver)
3412-
model.conflict_solver = solver
3413-
return
3414-
end
3415-
3416-
function MOI.get(optimizer::Optimizer, attr::MOI.ConflictStatus)
3417-
if optimizer.conflict_solver === nothing
3418-
return MOI.COMPUTE_CONFLICT_NOT_CALLED
3419-
end
3420-
return MOI.get(optimizer.conflict_solver, attr)
3421-
end
3422-
3423-
function MOI.get(
3424-
optimizer::Optimizer,
3425-
attr::MOI.ConstraintConflictStatus,
3426-
con::MOI.ConstraintIndex,
3427-
)
3428-
return MOI.get(optimizer.conflict_solver, attr, con)
3429-
end

test/test_moi_wrapper.jl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,74 @@ function test_multi_objective()
12781278
return
12791279
end
12801280

1281+
function _copy_conflict(model::MOI.ModelLike)
1282+
filter_fn(::Any) = true
1283+
function filter_fn(cref::MOI.ConstraintIndex)
1284+
for i in 1:MOI.get(model, MOI.ConflictCount())
1285+
status = MOI.get(model, MOI.ConstraintConflictStatus(i), cref)
1286+
if status != MOI.NOT_IN_CONFLICT
1287+
return true
1288+
end
1289+
end
1290+
return false
1291+
end
1292+
new_model = MOI.Utilities.Model{Float64}()
1293+
filtered_src = MOI.Utilities.ModelFilter(filter_fn, model)
1294+
MOI.copy_to(new_model, filtered_src)
1295+
MOI.set(new_model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)
1296+
return new_model
1297+
end
1298+
1299+
function _print_model(model)
1300+
return replace(sprint(print, model), "-0.0" => "0.0")
1301+
end
1302+
1303+
function _test_compute_conflict(input, output; silent::Bool = true, kwargs...)
1304+
model = MOI.instantiate(HiGHS.Optimizer; kwargs...)
1305+
MOI.set(model, MOI.Silent(), true)
1306+
MOI.set(model, MOI.TimeLimitSec(), 60.0)
1307+
MOI.Utilities.loadfromstring!(model, input)
1308+
MOI.optimize!(model)
1309+
@test MOI.get(model, MOI.ConflictCount()) == 0
1310+
MOI.compute_conflict!(model)
1311+
@test MOI.get(model, MOI.ConflictCount()) > 0
1312+
@test MOI.get(model, MOI.ConflictStatus()) == MOI.CONFLICT_FOUND
1313+
iis = _copy_conflict(model)
1314+
target = MOI.Utilities.Model{Float64}()
1315+
MOI.Utilities.loadfromstring!(target, output)
1316+
A, B = _print_model(iis), _print_model(target)
1317+
if A != B
1318+
@info "IIS"
1319+
print(A)
1320+
@info "Target"
1321+
println(B)
1322+
end
1323+
@test A == B
1324+
return
1325+
end
1326+
1327+
function test_relax_integrality_integer()
1328+
_test_compute_conflict(
1329+
"""
1330+
variables: x, y
1331+
maxobjective: 1.0 * x + y
1332+
2.0 * y <= 40.0
1333+
1.0 * x + y >= 35.0
1334+
x >= 0.0
1335+
x <= 10.0
1336+
x in Integer()
1337+
y >= 0.0
1338+
""",
1339+
"""
1340+
variables: x, y
1341+
2.0 * y <= 40.0
1342+
1.0 * x + y >= 35.0
1343+
x <= 10.0
1344+
""",
1345+
)
1346+
return
1347+
end
1348+
12811349
end # module
12821350

12831351
TestMOIHighs.runtests()

0 commit comments

Comments
 (0)