2015-10-14 71 views
3

我有兩個變量:x> = 0和y二進制(0或1),並且我有一個常數z> = 0。如何使用線性約束來描述以下條件:在線性編程中將條件約束轉換爲線性約束

If x = z then y = 1 else y = 0. 

我試圖通過定義另一個二元變量i和一個足夠大的正的常數U和添加約束

y - U * i = 0; 
x - U * (1 - i) = z; 

這是正確的解決這個問題?

回答

2

真的有兩類約束,你是問:

  1. 如果y=1,然後x=z。對於一些大的常M,你可以添加以下兩個約束來實現這一目標:
x-z <= M*(1-y) 
z-x <= M*(1-y) 

如果y=1那麼這些限制等同於x-z <= 0z-x <= 0,這意味着x=z,如果y=0,那麼這些制約因素是x-z <= Mz-x <= M,如果我們選擇了足夠大的值,則不應該具有約束力。

  1. if y=0 then x != z。從技術上講,您可以通過添加另一個二進制變量q來強制執行此約束,該變量控制是否x > zq=1)或x < zq=0)。然後,你可以添加以下的限制,其中m是一些小的正值和M是一些大的正值:

x-z >= mq - M(1-q) 
x-z <= Mq - m(1-q) 

如果q=1那麼這些限制必然x-z的範圍[m, M],如果q=0然後這些約束將x-z約束到範圍[-M, -m]

在實際使用求解器時,通常不會確保x != z,因爲通常允許小的邊界違例。因此,不要使用這些約束,我會建議不要爲您的模型添加任何約束來執行此規則。然後,如果您得到的最終解決方案爲y=0x=z,則可以調整x以取值x+epsilonx-epsilon,其值爲無限小的值epsilon

+0

@Bosco對不起,我不明白。 'x = z'很容易建模(我們在第1部分中做過)。 'x!= z'很難建模(正如我在第2部分中所描述的)。 – josliber

+0

Hi @josilber,所以條件是x = z,結果是y = 1,或者x!= z,結果是y = 0;通過你的約束,當x = z時,0 <= M *(1 - y),那麼y可以是1或0,這要多謝。 – Bosco

+0

@Bosco基本上我已經強制執行邏輯「如果y = 1」,那麼'x = z'「。當'y = 0'時,我沒有添加任何邏輯,所以在這種情況下你可以有'x = z'或'x!= z'。 – josliber

0

所以我改變條件制約

if x = z then y = 0 else y = 1 

那麼答案將是

x - z <= M * y; 
x - z >= m * y; 

其中M是一個足夠大的正數,m是一個足夠小的正數。

+0

如果'y = 0',那麼這些約束表明'x = z'(就像我的答案一樣)。然而,如果'y = 1',那麼你迫使'x-z'在'm'和'M'之間取值,這意味着你不允許'x!= z'和'x josliber

+0

Hi @josilber,所以我只能做比較x和z的範圍,我上面的答案是x不會小於z的情況。 – Bosco