@@ -438,7 +438,10 @@ 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 ! (
442+ status in
443+ (MOI. INFEASIBLE, MOI. ALMOST_INFEASIBLE, MOI. ALMOST_INFEASIBLE)
444+ )
442445 println (
443446 " iis resolver cannot continue because model is found to be $(status) by the solver" ,
444447 )
@@ -449,20 +452,45 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
449452 reference_map = MOI. copy_to (model, original_model)
450453 MOI. set (model, MOI. Silent (), true )
451454
455+ obj_sense = MOI. get (model, MOI. ObjectiveSense ())
456+ base_obj_type = MOI. get (model, MOI. ObjectiveFunctionType ())
457+ base_obj_func = MOI. get (model, MOI. ObjectiveFunction {base_obj_type} ())
458+
452459 constraint_to_affine =
453460 MOI. modify (model, MOI. Utilities. PenaltyRelaxation (default = 1.0 ))
454461 # might need to do something related to integers / binary
462+ relaxed_obj_type = MOI. get (model, MOI. ObjectiveFunctionType ())
463+ relaxed_obj_func = MOI. get (model, MOI. ObjectiveFunction {relaxed_obj_type} ())
464+
465+ pure_relaxed_obj_func = relaxed_obj_func - base_obj_func
455466
456467 max_iterations = length (constraint_to_affine)
457468
458469 tolerance = 1e-5
459470
460471 de_elastisized = []
461472
473+ changed_obj = false
474+
462475 for i in 1 : max_iterations
463476 MOI. optimize! (model)
464477 status = MOI. get (model, MOI. TerminationStatus ())
465- if status == MOI. INFEASIBLE
478+ if status in ( # possibily primal unbounded
479+ MOI. INFEASIBLE_OR_UNBOUNDED,
480+ MOI. DUAL_INFEASIBLE,
481+ MOI. ALMOST_DUAL_INFEASIBLE,
482+ )
483+ # try with a pure relaxation objective
484+ MOI. set (
485+ model,
486+ MOI. ObjectiveFunction {relaxed_obj_type} (),
487+ pure_relaxed_obj_func,
488+ )
489+ changed_obj = true
490+ MOI. optimize! (model)
491+ end
492+ if status in
493+ (MOI. INFEASIBLE, MOI. ALMOST_INFEASIBLE, MOI. ALMOST_INFEASIBLE)
466494 break
467495 end
468496 for (con, func) in constraint_to_affine
@@ -503,20 +531,58 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
503531 end
504532 end
505533
534+ if changed_obj
535+ MOI. set (
536+ model,
537+ MOI. ObjectiveFunction {relaxed_obj_type} (),
538+ relaxed_obj_func,
539+ )
540+ end
541+
506542 # consider deleting all no iis constraints
507543 # be careful with intervals
508544
545+ obj_type = MOI. get (model, MOI. ObjectiveFunctionType ())
546+ obj_func = MOI. get (model, MOI. ObjectiveFunction {obj_type} ())
547+ obj_sense = MOI. get (model, MOI. ObjectiveSense ())
548+
509549 # deletion filter
510550 cadidates = MOI. ConstraintIndex[]
511551 for (con, var, has_lower) in de_elastisized
512552 _set_bound_zero (model, var, has_lower, T)
513553 MOI. optimize! (model)
514554 status = MOI. get (model, MOI. TerminationStatus ())
515- if status in (MOI. INFEASIBLE, MOI. ALMOST_INFEASIBLE)
555+ if status in
556+ (MOI. INFEASIBLE, MOI. ALMOST_INFEASIBLE, MOI. ALMOST_INFEASIBLE)
516557 # this constraint is not in IIS
517- elseif status in (MOI. OPTIMAL, MOI. ALMOST_OPTIMAL)
558+ elseif status in (
559+ MOI. OPTIMAL,
560+ MOI. ALMOST_OPTIMAL,
561+ MOI. LOCALLY_SOLVED,
562+ MOI. ALMOST_LOCALLY_SOLVED,
563+ )
518564 push! (cadidates, con)
519565 _fix_to_zero (model, var, T)
566+ elseif status in (
567+ MOI. INFEASIBLE_OR_UNBOUNDED,
568+ MOI. DUAL_INFEASIBLE,
569+ MOI. ALMOST_DUAL_INFEASIBLE, # possibily primal unbounded
570+ )
571+ MOI. set (model, MOI. ObjectiveSense (), MOI. FEASIBILITY_SENSE)
572+ MOI. optimize! (model)
573+ primal_status = MOI. get (model, MOI. PrimalStatus ())
574+ if primal_status in (MOI. FEASIBLE_POINT, MOI. NEARLY_FEASIBLE_POINT)
575+ # this constraint is not in IIS
576+ push! (cadidates, con)
577+ _fix_to_zero (model, var, T)
578+ MOI. set (model, MOI. ObjectiveSense (), obj_sense)
579+ MOI. set (model, MOI. ObjectiveFunction {obj_type} (), obj_func)
580+ else
581+ error (
582+ " IIS failed due numerical instability, got status $status ," ,
583+ " then, for MOI.FEASIBILITY_SENSE objective, got primal status $primal_status " ,
584+ )
585+ end
520586 else
521587 error (" IIS failed due numerical instability, got status $status " )
522588 end
0 commit comments