0

我对 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
            )

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

4

2 回答 2

2

是的,这是首先添加所有变量的常用方法。请注意,该model.addVar()方法已经返回了无需调用即可直接使用的变量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提供变量值,其中.obobject_list

于 2022-01-17T21:10:47.973 回答
0

在任何情况下,您都应该考虑使用addVars()( documentation ) 并直接传递您的列表。这将返回一个tupledict,然后您可以使用它来制定您的约束和目标。

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

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

于 2022-01-18T09:31:04.787 回答