Почему я получаю GurobiError: переменная не в модели после использования Model.copy ()?

Мне нужно оптимизировать модель с разными наборами ограничений, но подмножество этих ограничений будет одинаковым для каждой модели. Моя идея заключалась в том, чтобы построить базовую модель со всеми переменными и всеми ограничениями, которые будут нужны каждый раз. Однако не похоже, что метод Gurobi Model.copy () копирует переменные так, как я себе представлял. Вот очень упрощенная версия того, что я надеюсь сделать, которая показывает ошибку, которую я получаю.

>>> from gurobipy import Model
>>> m0 = Model("test")
>>> v = m0.addVar(lb=-1, ub=1)
>>> m0.update()
>>> print m0
<gurobi.Model Continuous instance test: 0 constrs, 1 vars, Parameter changes: LogFile=gurobi.log>
>>> print v in m0.getVars()
True

>>> m = m0.copy()
>>> print m
<gurobi.Model Continuous instance test_copy: 0 constrs, 1 vars, Parameter changes: LogFile=gurobi.log>
>>> print v in m.getVars()
True

>>> m0.addConstr(v <= 0)
<gurobi.Constr *Awaiting Model Update*>
>>> m0.update()
>>> print m0
<gurobi.Model Continuous instance test: 1 constrs, 1 vars, Parameter changes: LogFile=gurobi.log>

>>> m.addConstr(v >= 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "model.pxi", line 2196, in gurobipy.Model.addConstr (../../src/python/gurobipy.c:66304)
  File "model.pxi", line 2089, in gurobipy.Model.__addConstr (../../src/python/gurobipy.c:64663)
gurobipy.GurobiError: Variable not in model

>>> print m
<gurobi.Model Continuous instance test_copy: 0 constrs, 1 vars, Parameter changes: LogFile=gurobi.log>
  1. Почему m.addConstr (v> = 0) не может найти переменную v, когда m.getVars () ясно показывает, что v присутствует в модели?
  2. Есть ли другой способ повторно использовать тот же набор переменных и ограничений, чтобы избежать перестройки каждой модели с нуля?

Программное обеспечение: Python 2.7.11 и Gurobi 6.5 на OS X El Capitan (также протестировано на Ubuntu 15.04)


person io.lite    schedule 16.05.2016    source источник


Ответы (1)


Я не смог найти четкого ответа на вопрос 1 о том, почему v в m.getVars () возвращает True в исходном примере. Я полагаю, что «in» - это только сравнение значений внутри объектов, а не самих объектов, но у меня нет источника для этого.

Что касается вопроса 2, я нашел решение:

  1. Создавайте переменные с именами, сохраняйте имена.
  2. Сделайте копию модели.
  3. Сопоставьте переменные в копии, используя имена.

Простой пример:

from gurobipy import Model
m0 = Model("test")
v_name = 'v'
v0 = m0.addVar(lb=-1, ub=1, name=v_name)
m0.update()

m = m0.copy()
# returns True
print v0 in m.getVars()

m0.addConstr(v0 <= 0)
m0.update()
# won't work
#m.addConstr(v0 >= 0)
# will work
v = m.getVarByName(v_name)
m.addConstr(v >= 0)
m.update()

Более сложный пример:

from gurobipy import Model
v_name = {}
m0 = Model("test")
v0 = {}
for i in range(10):
    v_name[i] = "v{0}".format(i)
    v0[i] = m0.addVar(lb=-1, ub=1, name=v_name[i])
m0.update()

m = m0.copy()
v = {}
for i in range(10):
    m0.addConstr(v0[i] <= 0)
    v[i] = m.getVarByName(v_name[i])
    m.addConstr(v[i] >= 0)
m0.update()
m.update()

... и так далее.

person io.lite    schedule 18.05.2016