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
516 stars 90 forks source link

Upper bound argument does not seem to have any effect on the assignment of binary variables #205

Closed kaibir closed 2 years ago

kaibir commented 2 years ago

Describe the bug

If adding an upper bound via 'ub=' argument to binary variable it has no effect.

To Reproduce

To reproduce use this very simple model:

my_model = mip.Model(name="my model", sense="MAX", solver_name="CBC")
var = my_model.add_var(name="ZeroVar", var_type=mip.BINARY, obj=1, ub=0.0)
my_model.optimize()

The objective value is 1.0 and also ZeroVar is 1.0

Expected behavior I would have expected that ZeroVar is 0.0 and also the objective value is.

If I add the additional constraint (which is in my eyes exactly what the ub should do) my_model.add_constr(var <= 0)

I get the expected result.

I know it may not make much sense to add an upper limit of 0 to a binary variable, but ignoring the upper limit for binary variables is not right in my eyes either.

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

tuliotoffolo commented 2 years ago

Thanks, @kaibir. Indeed, the code was forcing lb=0 and ub=1 for all binary variables:

if var_type == mip.BINARY:
    lb = 0.0
    ub = 1.0

Now ub is set to 1.0 only when the default value mip.INF is passed.

christian2022 commented 2 years ago

What about lb=1?

tuliotoffolo commented 2 years ago

The default is lb=0, but the user may now set lb=1. Here's the code that replaces the previous one:

if var_type == mip.BINARY:
    if ub == mip.INF:
        ub = 1.0
    if not (-mip.EPS <= lb <= 1.0 + mip.EPS and -mip.EPS <= ub <= 1.0 + mip.EPS):
        raise ValueError("Invalid bounds for a binary variable")