2016-12-07 75 views
2

我試圖在Python的PuLP中構造If-Then-Else-If ...條件。If-Then-ElseIf-Then在混合整數線性規劃

我看過MIP中的If-ThenIf-Then-Else。 但是,我想了解如何將選擇進一步傳播到下一組約束以及如何處理2個以上的決策分支。

爲了解釋,考慮在image shown here所示的條件限制:

x和y是我的決定變量。 基本上,這個讀作:

if x=0: C2>0 
elif x=1: C10>0 
elif x=2: C3>0 

if x=0 and y=0: 
    C4>0; 
    C8>0; 
    C10>0 
elif x=0 and y=1: 
    C5>0; 
    C8>0; 
    C10>0 
elif x=2 and y=0: 
    C6>0; 
    C9>0; 
    C10>0 
elif x=2 and y=1: 
    C7>0; 
    C9>0; 
    C10>0 

我知道如何使用 「大M」 技術,簡單的if-then-else的情況。因此,例如,如果問題是:

Problem: 
    if (x = 1) then (A < 0) else (B < 0) 
Solution: 
    problem += A < M1*(1-x) 
    problem += B < M2*x 

我不明白的是,如何改變這種爲:

  1. 如果有超過2個分支,所以它不再與乘法x和(1-x)。
  2. 如果後續分支低於原始決策,則更多決策都取決於上面的值。

回答

3

有真的在這裏涉及三個步驟:

FIRST:

重新制定x變量,所以它們是二進制的,而不是在{0,1,2}。 (嚴格地說,這是沒有必要的,但我認爲這使得該解決方案更清潔,更容易推廣。)

因此,推出三個新的二元變量x0x1x2和約束它們如下:

x0 >= 1 - x 
x0 <= 1 - 0.5x 

x2 >= x - 1 
x2 <= 0.5 x 

x1 = x - 2x2 

因此:如果是x = 0,那麼前兩個約束條件需要x0 = 1,後兩個需要x2 = 0,最後一個需要x1 = 0。並且類似地如果x = 1x = 2。 (您應該仔細檢查我的邏輯。)

您的模型將包含您的原始x變量以及新的二進制變量。

第二:

中創建一個新的二元決策變量,說w_ijkl,它等於1,如果x0 = ix1 = jx2 = ky = l,爲ijkl在{0,1}。通過下面的約束強制這樣的定義:

w_ijkl >= i*x0 + (1-i)*(1-x0) + j*x1 + (1-j)*(1-x1) + 
      k*x2 + (1-k)*(1-x2) + l*y + (1-l)*(1-y) - 3 
w_ijkl <= 0.25 * [i*x0 + (1-i)*(1-x0) + j*x1 + (1-j)*(1-x1) + 
        k*x2 + (1-k)*(1-x2) + l*y + (1-l)*(1-y)] 

第一個約束說,如果所有四個變量等於他們的目標(ij等),則w_ijkl必須等於1,否則它可以等於0。第二個約束說,如果所有四個相等他們的目標,然後w_ijkl可等於1,否則必須等於0。

因此,例如,w_0110得到這些約束:

w_0110 >= 1-x0 + x1 + x2 + (1-y) - 3 
w_0110 <= 0.25 * [1-x0 + x1 + x2 + (1-y)] 

第三:

根據需要使用big-M來打開和關閉約束。因此,例如,要求C6 >= 0如果x=2y=0,用途:

C6 >= M * (w_0010 - 1) 

(順便說一下,一般你不能在MIP使用嚴格的不等式約束 - 你需要大於 - 或 - 等於或小於或等於約束)。