Skip to content

Commit d7bb58d

Browse files
committed
Handle unboundedness in Infeasibility analysis
1 parent 242737c commit d7bb58d

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

src/infeasibility.jl

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
438438

439439
# handle optimize not called
440440
status = MOI.get(original_model, MOI.TerminationStatus())
441-
if status != MOI.INFEASIBLE
441+
if !(status in (MOI.INFEASIBLE, MOI.ALMOST_INFEASIBLE, MOI.ALMOST_INFEASIBLE))
442442
println(
443443
"iis resolver cannot continue because model is found to be $(status) by the solver",
444444
)
@@ -462,7 +462,7 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
462462
for i in 1:max_iterations
463463
MOI.optimize!(model)
464464
status = MOI.get(model, MOI.TerminationStatus())
465-
if status == MOI.INFEASIBLE
465+
if status in (MOI.INFEASIBLE, MOI.ALMOST_INFEASIBLE, MOI.ALMOST_INFEASIBLE)
466466
break
467467
end
468468
for (con, func) in constraint_to_affine
@@ -506,17 +506,46 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
506506
# consider deleting all no iis constraints
507507
# be careful with intervals
508508

509+
obj_type = MOI.get(model, MOI.ObjectiveFunctionType())
510+
obj_func = MOI.get(model, MOI.ObjectiveFunction{obj_type}())
511+
obj_sense = MOI.get(model, MOI.ObjectiveSense())
512+
509513
# deletion filter
510514
cadidates = MOI.ConstraintIndex[]
511515
for (con, var, has_lower) in de_elastisized
512516
_set_bound_zero(model, var, has_lower, T)
513517
MOI.optimize!(model)
514518
status = MOI.get(model, MOI.TerminationStatus())
515-
if status in (MOI.INFEASIBLE, MOI.ALMOST_INFEASIBLE)
519+
if status in (MOI.INFEASIBLE, MOI.ALMOST_INFEASIBLE, MOI.ALMOST_INFEASIBLE)
516520
# this constraint is not in IIS
517-
elseif status in (MOI.OPTIMAL, MOI.ALMOST_OPTIMAL)
521+
elseif status in (
522+
MOI.OPTIMAL, MOI.ALMOST_OPTIMAL, MOI.LOCALLY_SOLVED, MOI.ALMOST_LOCALLY_SOLVED,
523+
)
518524
push!(cadidates, con)
519525
_fix_to_zero(model, var, T)
526+
elseif status in (
527+
MOI.INFEASIBLE_OR_UNBOUNDED,
528+
MOI.DUAL_INFEASIBLE, MOI.ALMOST_DUAL_INFEASIBLE, # possibily primal unbounded
529+
)
530+
MOI.set(model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)
531+
MOI.optimize!(model)
532+
primal_status = MOI.get(model, MOI.PrimalStatus())
533+
if primal_status in (MOI.FEASIBLE_POINT, MOI.NEARLY_FEASIBLE_POINT)
534+
# this constraint is not in IIS
535+
push!(cadidates, con)
536+
_fix_to_zero(model, var, T)
537+
MOI.set(model, MOI.ObjectiveSense(), obj_sense)
538+
MOI.set(
539+
model,
540+
MOI.ObjectiveFunction{obj_type}(),
541+
obj_func,
542+
)
543+
else
544+
error(
545+
"IIS failed due numerical instability, got status $status,",
546+
"then, for MOI.FEASIBILITY_SENSE objective, got primal status $primal_status",
547+
)
548+
end
520549
else
521550
error("IIS failed due numerical instability, got status $status")
522551
end

0 commit comments

Comments
 (0)