coin-or / python-mip

Python-MIP: collection of Python tools for the modeling and solution of Mixed-Integer Linear programs
Eclipse Public License 2.0
533 stars 93 forks source link

CBC interface only partially reassigns objective #71

Closed pgoelz closed 4 years ago

pgoelz commented 4 years ago

Minimal example:

from mip import *
m = Model(sense=MAXIMIZE, solver_name=CBC)
v1 = m.add_var(var_type=BINARY)
v2 = m.add_var(var_type=BINARY)
m.add_constr(v1 + v2 == 1)

m.objective = 500 * v1
m.optimize()
> <OptimizationStatus.OPTIMAL: 0>
v1.x, v2.x
> (1, 0)

m.objective = v2
m.optimize()
> <OptimizationStatus.OPTIMAL: 0>
v1.x, v2.x
> (1, 0)

What I would have expected: (0, 1) as a result of the last call, because this assignment maximizes the updated objective v2. This is the behavior for gurobi, but not for CBC.

Suspected reason: In https://github.com/coin-or/python-mip/blob/master/mip/cbc.py#L1561-L1564 , it seems that, for variables not appearing in the new objective, their coefficients are not reset to 0. In the example above, the second optimization tries to maximize 500 v1 + v2 rather than v2. Possibly, the line https://github.com/coin-or/python-mip/blob/b1edfec72ba5a634e56674eb79dce32f63c6596d/mip/gurobi.py#L783 ensures that the same problem does not appear using Gurobi?

Versions: I am using mip version 1.7.2 (from pip) on Python 3.7.6 and OSX 10.15.3.

For the time being, is there a work-around that does not require creating a new model? I was thinking of setting m.objective = 0 * v1 + v2, but the 0 coefficient seems to get optimized away before set_objective().

h-g-s commented 4 years ago

Hi @pgoelz , I just commited an attempt to fix it. Could you download the "cbc.py" file from master and update manually in your installation to see if it works ?

pgoelz commented 4 years ago

Thanks, @h-g-s! Your changes fix the problem on my system.

In case anyone is looking for a workaround before the next release, resetting the coefficient of v1 via v1.obj = 0 seems to work.