model.update 在模型中的表现

model.update performance in the model

我对 gurobipy 库中 model.update 的性能有疑问。

假设我有一个对象列表,我想将其作为变量添加到模型中,我还想为每个对象添加一个约束,为此我有一个 for 循环,我在其中执行以下

for object in list:
    some_parameter=object.parameter
    model.addVar(name=object.name)
    model.update()
    model.addConstr(
                model.getVarByName(object_name) >= some_parameter
            )

当然我的循环比较复杂,这只是一个简单的例子。我在日志中收到此消息:

信息:警告:模型更新花费的时间过多。 信息:考虑降低调用更新的频率。

我现在的问题是:正确的解决方案是制作两个循环而不是像这样的循环:

for object in list:
    model.addVar(name=object.name)

然后打电话

    model.update()

然后 运行 添加约束的循环?

for object in list:
    some_parameter=object.parameter
    model.addConstr(
                model.getVarByName(object_name) >= some_parameter
            )

哪一个是通常的方法,或者我应该完全不同?

是的,这是先添加所有变量的通常方法。注意model.addVar()方法已经returns了变量,可以不用调用model.update()直接使用。因此,您不需要 model.getVarByName() 方法来获取对变量的访问。相反,您可以这样做:

# add the variables
y = {}
for ob in object_list:
    y[ob.name] = model.addVar(name=ob.name)

# add the constraints
for ob in object_list:
    model.addConstr(y[ob.name] >= ob.parameter)

model.update()
model.optimize()

模型求解后,您可以通过 .X 属性轻松访问变量值,即 y[ob.name].X 为您提供变量值,其中 ob 是你的 object_list.

在任何情况下,您都应该考虑使用 addVars()documentation) and pass your list directly. This will return a tupledict,然后您可以使用它来制定约束和 objective。

这种方法通常是最快和最 pythonic 的,因为您不使用任何手动 for 循环,同时仍然提供对变量的轻松访问。

最后,在大多数情况下,调用 update() 是没有必要的,尤其是在调用 optimize() 之前,因为无论如何都会发生隐式 update() 调用。