2017-06-16 38 views
0

我想創建一個函數,當我嘗試訪問帶有無效索引的索引變量時返回默認值(= 0)。這是我到目前爲止所做的。Pyomo函數每當發生索引錯誤時都返回默認值

def SafeguardIdx(object, index_set): 
    print("Guarded {} with index {}".format(object.name, index_set), index_set in object.index_set()) 
    return base.expr.Expr_if(IF=index_set in object.index_set(), THEN=object[index_set], ELSE=0) 

這就是我得到:

Guarded ENDINVW_jwt with index (1, 1, 0) False 
KeyError: "Error accessing indexed component: Index '(1, 1, 0)' is not valid for array component 'ENDINVW_jwt'" 

爲什麼訪問索引即使 「IF =」 的計算結果爲假?

編輯:我還想問一下,如果我的落實分鐘()函數是正確的:

def PyomoMin(a, b): 
    return base.expr.Expr_if(IF=(a > b), THEN=(a), ELSE=(b)) 

提前感謝!

回答

2

你想要的東西沒有意義。 Expr_if構造將3個參數的節點添加到表達式圖形中。也就是說,要定義表達式,IF,THEN和ELSE子句都必須是有效的Pyomo表達式。如果可以在生成模型時評估表達式(例如,索引不存在),則不應使用Expr_ifSafeguardIdx可以用簡單的python if來實現。

至於實施min(),您的實現

def PyomoMin(a, b): 
    return base.expr.Expr_if(IF=(a > b), THEN=(a), ELSE=(b)) 

實際上實現了max()。如果您想要min(),則需要反轉比較或指定THEN=b, ELSE=a。也就是說,這通常不是實施min()的推薦方式。有幾個問題,這一提法(見Constraints involving max in a linear program?):

  1. Expr_if只能通過NL接口(所以你不能將它發送到LP/MIP求解器)。
  2. min()並不順利(其中大部分NL求解需要),所以NL求解器可能收斂的問題(特別是如果該解決方案是不遠的地方a == b

有替代品制定min,但他們都涉及增加額外的變量/限制,而「最佳」取決於你的其他模型。最簡單的方法是引入一個額外變量(例如,minab),然後將其限制爲小於ab。如果客觀壓力試圖最大化minab,那麼你沒問題。但是,如果目標想要最小化minab,那麼您的問題可能會變得無限或返回無意義的答案。在這種情況下,您還需要實施約束minab >= min(a,b),這很棘手。 MIPS的,通常的解決辦法是引入一個二元變量,放鬆約束,例如:

minab >= a - M*y 
minab >= b - M*(1-y) 

對於非線性模型您經常要避免引進的二進制文件,如果你的模型還沒有他們。有些選項可以通過諸如恭維約束或通過abs()的平滑近似值來處理。

0

我發現原帖的工作解決方案。

def SafeIdx(item, *index_set, default=0): 
    return item[index_set] if index_set in item.index_set() else default