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
538 stars 95 forks source link

Confusing Behaviour with disposing of Gurobi Environment #347

Open TPreece101 opened 1 year ago

TPreece101 commented 1 year ago

Describe the bug I have a single use Gurobi licence so I can't have more than one Gurobi environment running at the same time. However, I'm getting some confusing behaviour when trying to clean up the Gurobi environment after a run.

To Reproduce So if I firstly run this:

import gurobipy as gp
from itertools import product
from mip import Model

model = Model(solver_name='GUROBI')

x = model.add_var(name="X", lb=10, ub=80)
model.objective = x
status = model.optimize()

print(status)

# Create a new model
m = gp.Model()

# Create variables
x = m.addVar(vtype='B', name="x")

# Set objective function
m.setObjective(x, gp.GRB.MAXIMIZE)

# Solve it!
m.optimize()

print(f"Optimal objective value: {m.objVal}")
print(f"Solution values: x={x.X}, y={y.X}, z={z.X}")

gp.disposeDefaultEnv()

Then I get an error GurobiError: Single-use license. Another Gurobi process with pid 3981 running. when it tries to create a new model using gp.Model().

So then I tried to dispose of the model using del model first like so:

import gurobipy as gp
from itertools import product
from mip import Model

model = Model(solver_name='GUROBI')

x = model.add_var(name="X", lb=10, ub=80)
model.objective = x
status = model.optimize()

print(status)

del model

# Create a new model
m = gp.Model()

# Create variables
x = m.addVar(vtype='B', name="x")

# Set objective function
m.setObjective(x, gp.GRB.MAXIMIZE)

# Solve it!
m.optimize()

print(f"Optimal objective value: {m.objVal}")
print(f"Solution values: x={x.X}, y={y.X}, z={z.X}")

gp.disposeDefaultEnv()

However this produces the same error.

The thing that confuses me is that it works when I delete the solver directly like so:

import gurobipy as gp
from itertools import product
from mip import Model

model = Model(solver_name='GUROBI')

x = model.add_var(name="X", lb=10, ub=80)
model.objective = x
status = model.optimize()

print(status)

del model.solver

# Create a new model
m = gp.Model()

# Create variables
x = m.addVar(vtype='B', name="x")

# Set objective function
m.setObjective(x, gp.GRB.MAXIMIZE)

# Solve it!
m.optimize()

print(f"Optimal objective value: {m.objVal}")
print(f"Solution values: x={x.X}, y={y.X}, z={z.X}")

gp.disposeDefaultEnv()

The thing I don't understand is that this line: https://github.com/coin-or/python-mip/blob/master/mip/model.py#L135-L136 implies that when we do del model then it should be doing del model.solver under the hood. So I don't understand why del model.solver works but del model doesn't.

Steps to reproduce the behavior please include attached any files needed to reproduce the error. We can only help you if we can reproduce the error ourselves and debug.

Expected behavior I would expect both del model and del model.solver to clean up the Gurobi environment.

Desktop (please complete the following information):

Let me know if you need any more information 😊

BiancaZYCao commented 1 year ago

I faced the same issue on my Gurobi floating license. Any updates on this? Python version: 3.9 Gurobi version: 9