Search code examples
pythonoptimizationpulpcoin-or-cbc

Detect presolve status in pulp model


Hi I am running a model using pulp CBC and have few constraints in the model that may make the model infeasible if wrong input is given to the model.

I can see while my model runs that in case of infeasible model, I can see an output in terminal that says presolve detects 1 infeasibility. After this line my model starts solving and no surprise gives me an output that my solution is infeasible.

My question is, how can I stop my program if presolve is saying my model is infeasible? Is there any way to detect that as I don't want to spend time solving a model which presolve says is infeasible.

Problem Background:

I have a hard constraint in my model, which can make my model infeasible in some cases, I want my program (and not OR model) to detect this infeasibility and make that constraint soft.

One way to achieve this is let my complete program run and then detect result_status but as model can take quite some time to run and I don't want to spend time considering I have to take another run with Soft Constraint. I am thinking is there any way I can detect and stop my model if presolve say model is infeasible.

LP File with some rows removed:

Welcome to the CBC MILP Solver 
Version: 2.10.3 
Build Date: Dec 15 2019 

command line - "PATH" max sec 3000 ratio 1e-05 timeMode elapsed branch printingOptions all solution "PATH"\f5c13890167e459ea27741f1c5d52d5c-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 95389 COLUMNS
At line 611896 RHS
At line 707281 BOUNDS
At line 707282 ENDATA
Problem MODEL has 95384 rows, 175589 columns and 341444 elements
Coin0008I MODEL read with 0 errors
seconds was changed from 1e+100 to 3000
ratioGap was changed from 0 to 1e-05
Option for timeMode changed from cpu to elapsed
Presolve determined that the problem was infeasible with tolerance of 1e-08
Analysis indicates model infeasible or unbounded
1 infeasibilities
Analysis indicates model infeasible or unbounded
Perturbing problem by 0.001% of 5262.5816 - largest nonzero change 0.0052725434 ( 9.7117787%) - largest zero change 0.0026361607
0  Obj -0 Primal inf 7.4173266e+08 (10627) Dual inf 1.383116e+10 (56881)
0  Obj -0 Primal inf 7.4173266e+08 (10627) Dual inf 6.2882648e+14 (66006)

Primal infeasible - objective value -6.0887206e+12
PrimalInfeasible objective -6.088720618e+12 - 108021 iterations time 88.622

Result - Linear relaxation infeasible

Enumerated nodes:           0
Total iterations:           0
Time (CPU seconds):         89.03
Time (Wallclock Seconds):   89.03

Option for printingOptions changed from normal to all
Total time (CPU seconds):       89.91   (Wallclock seconds):       89.91

Solution

  • Why not make the problem elastic with a high penalty?

    model.extend(
         pp.LpConstraint(
             e =VARIABLE,
             sense = pp.LpConstraintLE,
             rhs=MAX_VALUE_ACCEPTABLE
             name=f"permissive_elastic"
         ).makeElasticSubProblem(
             penalty=1000
             proportionFreeBoundList=[1,0]
         )
    

    That way the model will do all it can to keep variable under its max acceptable value to avoid tanking the objective value with it's high penalty. Only if it is infeasible with that condition will it relax the condition and allow higher values.