@@ -438,7 +438,10 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
438
438
439
439
# handle optimize not called
440
440
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
+ )
442
445
println (
443
446
" iis resolver cannot continue because model is found to be $(status) by the solver" ,
444
447
)
@@ -449,20 +452,45 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
449
452
reference_map = MOI. copy_to (model, original_model)
450
453
MOI. set (model, MOI. Silent (), true )
451
454
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
+
452
459
constraint_to_affine =
453
460
MOI. modify (model, MOI. Utilities. PenaltyRelaxation (default = 1.0 ))
454
461
# 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
455
466
456
467
max_iterations = length (constraint_to_affine)
457
468
458
469
tolerance = 1e-5
459
470
460
471
de_elastisized = []
461
472
473
+ changed_obj = false
474
+
462
475
for i in 1 : max_iterations
463
476
MOI. optimize! (model)
464
477
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)
466
494
break
467
495
end
468
496
for (con, func) in constraint_to_affine
@@ -503,20 +531,58 @@ function iis_elastic_filter(original_model::MOI.ModelLike, optimizer)
503
531
end
504
532
end
505
533
534
+ if changed_obj
535
+ MOI. set (
536
+ model,
537
+ MOI. ObjectiveFunction {relaxed_obj_type} (),
538
+ relaxed_obj_func,
539
+ )
540
+ end
541
+
506
542
# consider deleting all no iis constraints
507
543
# be careful with intervals
508
544
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
+
509
549
# deletion filter
510
550
cadidates = MOI. ConstraintIndex[]
511
551
for (con, var, has_lower) in de_elastisized
512
552
_set_bound_zero (model, var, has_lower, T)
513
553
MOI. optimize! (model)
514
554
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)
516
557
# 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
+ )
518
564
push! (cadidates, con)
519
565
_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
520
586
else
521
587
error (" IIS failed due numerical instability, got status $status " )
522
588
end
0 commit comments