[英]PuLP Conditional Constraint Sum (Based on Variable)
I am trying to optimize a problem where the decision variable (X) is a NxN binary matrix.我正在尝试优化决策变量 (X) 是 NxN 二进制矩阵的问题。 I am finding trouble making one of the constraints of the problem work.
我发现使问题的约束之一起作用时遇到了麻烦。
The first constraint implies that the sum of X in each row must be == 1. (Covered)第一个约束意味着每行中 X 的总和必须 == 1。(已覆盖)
The second constraint (the one I cannot make to work) requires that for those columns where the diagonal is == 1, the sum of X must be >= 2. I have generated the following constraint in PuLP:第二个约束(我无法使用的约束)要求对于对角线 == 1 的那些列,X 的总和必须 >= 2。我在 PuLP 中生成了以下约束:
for j in W:
prob += sum(X[i][j] for i in W if X[j][j] >= 1) >= 2
PuLP indicates the solution status is 'Infeasible'. PuLP 指示解决方案状态为“不可行”。 ¿What am I getting wrong?
¿ 我做错了什么? ¿This constraint cannot be implemented in PuLP?
¿ 这个约束不能在纸浆中实现?
Essentially, an example solution matrix that covers the previous requirements would be:本质上,涵盖先前要求的示例解决方案矩阵将是:
[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]
This is a linear-programming framework and therefore only linear functions can be used .这是一个线性规划框架,因此只能使用线性函数。 Arbitrary python-expressions like:
任意 python 表达式,如:
if
abs
min
are not passed to the solver, but are evaluated a-priori (the modelling-framework / solver do not see this) usually resulting in garbage.不会传递给求解器,而是先验地评估(建模框架/求解器看不到这一点)通常会导致垃圾。
These kind of things must be linearized .这类事情必须线性化。 Some frameworks can provide some of those automatically, but that is a very tough task in general (as most linearizations are impossible without model-specific assumptions.).
一些框架可以自动提供其中的一些,但这通常是一项非常艰巨的任务(因为如果没有特定于模型的假设,大多数线性化是不可能的。)。
( cvxpy for example supports re-formulation of abs
and min
while being compatible with some rule-set) (例如cvxpy支持
abs
和min
的重新制定,同时与某些规则集兼容)
Here you will need to do this yourself.在这里,您需要自己执行此操作。
If i understood the task correctly, it looks like:如果我正确理解了任务,它看起来像:
Example solution:示例解决方案:
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
We can linearize the expression as:我们可以将表达式线性化为:
for column in columns:
(1-diag_elem_of_column) * bigM + sum(column) >= 2
<->
(1-diag_elem_of_column) * 2 + sum(column) >= 2
This is a classic big-M formulation, where there is some binary indicator variable (diagonal-element) activating/deactivating some linear expression using some large constant big-M .这是一个经典的 big-M 公式,其中有一些二进制指示变量(对角元素)使用一些大常数 big-M激活/停用一些线性表达式。 This large constant makes those approaches dependent on assumptions, but in your case this large constant does not need to be very large (and tightening is important for the integrality-gap -> better for the solver).
这个大常数使这些方法依赖于假设,但在您的情况下,这个大常数不需要非常大(并且紧缩对于完整性间隙很重要 -> 对求解器更好)。
The idea is:这个想法是:
sum(column) >= 2
except when there is no diagonal-element hitsum(column) >= 2
除非没有对角元素命中 Code-wise this could look like (untested):代码方面,这可能看起来像(未经测试):
# 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.