2014-05-13 19 views
1

有人可以幫我解決這個錯誤嗎? 何處shoudl我看到當我得到錯誤:GurobiError:無法將參數轉換爲表達式。 我要補充一點,我使用Gurobi庫在PythonGurobiError:無法將參數轉換爲表達式

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

回答

0

如果您嘗試添加一個約束,沒有模型變量Gurobi會抱怨。它看起來像一些變量組合列表枚舉構造空列表,即:

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

又名

m.addConstr(-1 == 0)

這是不可能的。實際上gurobi仍然會在下面的例子中拋出一個錯誤,即使這個表達式不可能包含變量。

m.addConstr(-1 <= 0)

爲了解決這個問題只是檢查列表添加約束之前,非空。

0

此問題已在Gurobi 6.0.0中修復。 quicksum([])返回值爲0的線性表達式(而不是浮點數0.0),這解決了原始問題。

版本5.6.3和之前的問題是使用所謂的TempConstr

當你調用addConstr,你可以使用顯式 「lefthandside」, 「經營者」, 「的右手邊」 的方法:

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

這不會有任何問題的工作。

如果使用TempConstr和一個空表上使用quicksum,真正那張如下:

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

quicksum返回0,如果列表是空的,所以你的說法是:

m.addConstr(0 == 0) 

0 == 0轉換爲True,所以你實際調用:

m.addConstr(True) 

這顯然是Gurobi無法處理的(但它可以給出更好的錯誤描述)。總結一下:如果你使用quicksum,並且有一個機會,列表是空的,你可以檢查列表是否爲空,正如blunevelope建議的那樣,使用明確的方法或者使用小的包裝器方法,如果這種情況經常發生:

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表達式。

相關問題