coin-or / Cbc

COIN-OR Branch-and-Cut solver
Other
808 stars 115 forks source link

ratioGap not being enforced? #536

Open gameveloster opened 2 years ago

gameveloster commented 2 years ago

Hello, I'm running cbc using Python's pyomo package with the ratioGap option set to a high value of 0.9, so I expect the solver to terminate very quickly after starting.

However, it appears to ignore the ratioGap option and solve it to optimality. Is this expected, or do I have an incorrect understanding of what ratioGap is supposed to do?

ratioGap also appears to be ignored when I try other values like 0.99, 0.5, 0.1 and 0.01. In all these cases, the number of iterations ran is the same.

I'm using CBC 2.10.5, pyomo 6.4.1 and Python 3.10.4, Ubuntu 20.04.

Thank you for any help!

Logs:

Solver command line: ['/opt/anaconda3/envs/or/bin/cbc', '-ratioGap', '0.9', '-printingOptions', 'all', '-import', '/tmp/tmpqsr5ldk_.pyomo.lp', '-stat=1', '-solve', '-solu', '/tmp/tmpqsr5ldk_.pyomo.soln']

Welcome to the CBC MILP Solver 
Version: 2.10.5 
Build Date: Dec  8 2020 

command line - /opt/anaconda3/envs/or/bin/cbc -ratioGap 0.9 -printingOptions all -import /tmp/tmpqsr5ldk_.pyomo.lp -stat=1 -solve -solu /tmp/tmpqsr5ldk_.pyomo.soln (default strategy 1)
ratioGap was changed from 0 to 0.9
Option for printingOptions changed from normal to all
Presolve 400 (-1) rows, 40000 (-1) columns and 80000 (-1) elements
Statistics for presolved model

Problem has 400 rows, 40000 columns (40000 with objective) and 80000 elements
Column breakdown:
40000 of type 0.0->inf, 0 of type 0.0->up, 0 of type lo->inf, 
0 of type lo->up, 0 of type free, 0 of type fixed, 
0 of type -inf->0.0, 0 of type -inf->up, 0 of type 0.0->1.0 
Row breakdown:
0 of type E 0.0, 400 of type E 1.0, 0 of type E -1.0, 
0 of type E other, 0 of type G 0.0, 0 of type G 1.0, 
0 of type G other, 0 of type L 0.0, 0 of type L 1.0, 
0 of type L other, 0 of type Range 0.0->1.0, 0 of type Range other, 
0 of type Free 
Presolve 400 (-1) rows, 40000 (-1) columns and 80000 (-1) elements
Perturbing problem by 0.001% of 99 - largest nonzero change 0.00059323787 ( 0.01044271%) - largest zero change 0
0  Obj 0 Primal inf 399.9996 (400)
83  Obj 89.00428 Primal inf 289.99971 (287)
166  Obj 148.00814 Primal inf 222.29978 (216)
249  Obj 195.71159 Primal inf 186.89981 (193)
332  Obj 250.714 Primal inf 107.69987 (134)
415  Obj 268.71557 Primal inf 53.999907 (93)
498  Obj 275.01551 Primal inf 21.099978 (22)
501  Obj 276.01533
Optimal - objective value 276
After Postsolve, objective 276, infeasibilities - dual 0 (0), primal 0 (0)
Optimal objective 276 - 501 iterations time 0.032, Presolve 0.02
Total time (CPU seconds):       0.73   (Wallclock seconds):       0.21

Problem File: tmpqsr5ldk_.pyomo.lp

Solution File: tmpqsr5ldk_.pyomo.soln

PS: I'm sort of curious why the obj values in the logs are increasing when this is a minimization problem

svigerske commented 2 years ago

The Obj in the log is from the LP solver, so it's about solving the relaxation. The gap is only checked after the LP relaxation has been solved. In this case, it looks like the solution of the LP relaxation is also feasible for the problem itself, so the gap is zero.

If your problem is actually an LP, then the answer is that the ratioGap doesn't apply here. That's for MIPs or other problems that are solved by methods where primal and dual bounds are computed separately.

The objective increases because Clp has decided to start at an infeasible point with objective value 0 and then works its way towards a feasible point. The more feasible it gets, the worse becomes the objective function value.