[英]PuLP Conditional Constraint Sum (Based on Variable)
我正在嘗試優化決策變量 (X) 是 NxN 二進制矩陣的問題。 我發現使問題的約束之一起作用時遇到了麻煩。
第一個約束意味着每行中 X 的總和必須 == 1。(已覆蓋)
第二個約束(我無法使用的約束)要求對於對角線 == 1 的那些列,X 的總和必須 >= 2。我在 PuLP 中生成了以下約束:
for j in W:
prob += sum(X[i][j] for i in W if X[j][j] >= 1) >= 2
PuLP 指示解決方案狀態為“不可行”。 ¿ 我做錯了什么? ¿ 這個約束不能在紙漿中實現?
本質上,涵蓋先前要求的示例解決方案矩陣將是:
[0,0,0,1,0]
[0,0,0,1,0]
[0,0,0,1,0]
[0,0,0,0,1]
[0,0,0,0,1]
這是一個線性規划框架,因此只能使用線性函數。 任意 python 表達式,如:
if
abs
min
不會傳遞給求解器,而是先驗地評估(建模框架/求解器看不到這一點)通常會導致垃圾。
這類事情必須線性化。 一些框架可以自動提供其中的一些,但這通常是一項非常艱巨的任務(因為如果沒有特定於模型的假設,大多數線性化是不可能的。)。
(例如cvxpy支持abs
和min
的重新制定,同時與某些規則集兼容)
在這里,您需要自己執行此操作。
如果我正確理解了任務,它看起來像:
示例解決方案:
D! D!
1 0 0 0 sum = 1
1 0 0 0 sum = 1
0 0 1 0 sum = 1
0 0 1 0 sum = 1
sums
2 0 2 0
我們可以將表達式線性化為:
for column in columns:
(1-diag_elem_of_column) * bigM + sum(column) >= 2
<->
(1-diag_elem_of_column) * 2 + sum(column) >= 2
這是一個經典的 big-M 公式,其中有一些二進制指示變量(對角元素)使用一些大常數 big-M激活/停用一些線性表達式。 這個大常數使這些方法依賴於假設,但在您的情況下,這個大常數不需要非常大(並且緊縮對於完整性間隙很重要 -> 對求解器更好)。
這個想法是:
sum(column) >= 2
除非沒有對角元素命中代碼方面,這可能看起來像(未經測試):
# assumption: square-matrix
# assumption: X[row][col] storage-order
N = 5
for diag_element_index, col in enumerate(N):
prob += (1 - X[diag_element_index][col]) * 2 + sum([X[row][col] for row in range(N)]) >= 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.