2013-08-20 205 views
1

我通過C#API使用CPLEX 12.5.0.0。使用CPLEX進行二次規劃的目標常數?

到現在爲止,我從來沒有過一個具有常數項的目標 - 只有約束條件。有了約束,我總能重新排列方程,所以常數總是在一邊,這意味着每個ILinearNumExpr本身沒有常數項。

現在我有一個二次規劃問題,具有以下類型的一個目的:

MAX Z = 
    c[1,2] * a[1] * a[2] - c[1,2] * (1 - a[1] * a[2]) + 
    c[1,3] * a[1] * a[3] - c[1,2] * (1 - a[1] * a[3]) + 
    c[2,3] * a[2] * a[3] - c[2,2] * (1 - a[2] * a[3]) 

C [,]是一個常數,對稱成本矩陣。 a [i]是二元變量。

因此,看着上面三行的左半部分,將[i]和a [j]放在一起會使客觀價值成爲c [i,j]。這是目前實施,測試和工作的內容。

我想修改目標,以便如果[i]和a [j]不都等於1,而不是不向目標值貢獻c [i,j],則會將其減去。

現在,我查閱了CPLEX文檔(作者顯然對提供清晰的解釋或示例過敏),並且似乎有一個ILinearNumExpr.Constant屬性,它允許我爲給定表達式設置常量。

當我試圖修改我的代碼IQuadNumExpr,我注意到它沒有那.Constant屬性。

有什麼方法可以將常數項添加到二次客觀函數函數在CPLEX中嗎?

+0

c [1,2] a [1] a [2] -C [1,2](1-a [1] a [2]) == 2c [1,2] x [1] x [2] - c [1,2]。那真的是你想要做的嗎? –

+0

@DavidNehme是的,你可以重新安排這樣的表達。我以這種形式離開,因爲它更容易理解和解釋。然而,重新安排並沒有改變我的問題,因爲在目標函數中仍然存在一個-c [1,2]常數項。 – Ozzah

+0

您可以忽略目標函數中的常數項。常數項不會改變最佳解決方案。另外,由於[i]是二進制的,所以最好將它建模爲線性MIP。 –

回答

1

要回答您的具體問題,要向二次目標函數添加常數,可以使用cplex對象的.Sum方法。例如

cplex.AddMaximize(cplex.sum(quadExpr, cplex.Constant(10)); 

使目標函數quadExpr + 10

現在,對您的其他帖子發表兩條評論。首先,目標函數的任何線性變換都不會對您的解決方案產生任何影響。所以,如果要最大化要麼

quadExpr 

m * quadExpr + c 

是等價的任何(非零)常數m和常數c。

接下來,由於二次表達式中的變量是二元的,因此通過制定混合整數線性模型,您幾乎總能做得更好。要做到這一點,你需要創建一個額外的線性變量集合,比如b [i] [j],只有當x [i]和a [j]都是1時,它纔是1。您可以通過添加約束

b[i][j] <= x[i] 
b[i][j] <= x[j] 

如果你能夠最大限度地執行B [] []的財產,和c [i] [j]> = 0,那麼你就需要明確執行逆,但如果情況並非如此,則可以添加

x[i] + x[j] <= 1 + b[i][j] 
+0

感謝您的回答。正如我之前所說的,使模型線性化所增加的變量和限制實際上使解決問題需要更長的時間。我可以在幾個小時內解決QP問題,而BIP可以持續很多天。 – Ozzah