1

有人可以帮我解决这个错误吗?当我收到错误时我应该在哪里看:GurobiError:无法将参数转换为表达式。我应该补充一点,我在 python 中使用 Gurobi 库

from gurobipy import*

m=Model('mymodel')

def label(c):
    return "x" + str(c).translate(None, " '")

shifts = [1,2]    
hours = [1,2]
games = ['bj', 'cr']
pits = [1,2]
order1 = [1,2]
order2 = [1,2,3]
combo, oi = multidict( {
 (1,1,'bj',1,1,1): 100,
 (1,1,'bj',1,1,2):200,
 (1,1,'bj',1,1,3):200,
 (1,1,'bj',1,2,1):50,
 (1,1,'bj',1,2,2):70,
 (1,1,'bj',1,2,3):70,
 (1,1,'cr',1,1,1):400,
 (1,1,'cr',1,1,2):450
})

combo= tuplelist(combo)
for s  in shifts:
    for t in hours:
        for i in games:
            for n in order1:
                     m.addConstr(quicksum(x[s,t,i,p,n,k] for s,t,i,p,n,k in combo.select(s,t,i,'*',n,'*'))- int(1)== 0, name=label((s,t,i,p,n,k))
4

2 回答 2

0

如果您尝试添加没有模型变量的约束,Gurobi 会抱怨。看起来对于某些变量组合,列表枚举将构造空列表,即:

m.addConstr(quicksum([]) - 1 == 0)

又名

m.addConstr(-1 == 0)

这是不可能的。事实上,即使表达式不包含变量是可行的,gurobi 仍然会在以下示例中引发错误。

m.addConstr(-1 <= 0)

要解决这个问题,只需在添加约束之前检查列表是否为空。

于 2014-09-17T07:19:07.637 回答
0

此问题已在 Gurobi 6.0.0 中修复。quicksum([])返回值为 0 的线性表达式(而不是浮点 0.0),这解决了原始问题。

5.6.3 及之前版本中的问题是使用所谓的TempConstr

当您调用addConstr时,您可以使用显式的“lefthandside”、“operator”、“righthandside”方法:

m.addConstr(quicksum([]), GRB.EQUAL, 0)

这将毫无问题地工作。

如果您使用TempConstrquicksum在一个空列表上使用,那么真正发生的情况如下:

m.addConstr(quicksum([]) == 0)

quicksum如果列表为空,则返回 0,因此您的语句是:

m.addConstr(0 == 0)

0 == 0转换为True,因此您实际上调用:

m.addConstr(True)

这显然是 Gurobi 无法处理的事情(但它可以提供更好的错误描述)。

总结一下:如果您使用 quicksum 并且有可能列表为空,您可以按照 blueenvelope 的建议检查列表是否为空,使用显式方法或使用小型包装方法,如果这种情况发生经常:

def add_constr(model, expression, name=""):
    if expression is True:
        return model.addConstr(0, GRB.EQUAL, 0, name)
    elif expression is False:
        raise Exception('`False` as constraint for {}'.format(name))
    else:
        return model.addConstr(expression, name)

此包装器仅适用于 TempConstr 作为表达式。

于 2014-10-24T06:31:31.877 回答