簡體   English   中英

PuLP條件約束總和(基於變量)

[英]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支持absmin的重新制定,同時與某些規則集兼容)

在這里,您需要自己執行此操作。

如果我正確理解了任務,它看起來像:

  • 二進制矩陣
  • 每行總和為 1
  • 每個列總和都是不受約束的,除了一列,其中對角線 position 有一個 1 -> 然后這個列總和的下限為 2

示例解決方案:

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除非沒有對角元素命中
  • 當存在對角元素命中時 -> (1-diag_elem_of_column) * 2 = 0 -> 總和被限制為 >= 2(因為我們需要在剩余變量中獲得 2 個非零)
  • 當沒有對角元素命中時 -> (1-diag_elem_of_column) * 2 = 2 >= 2 (剩余元素的總和是免費的 -> 沒有限制,因為我們已經滿足了最小值 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM