纸浆:如何编写多变量约束?

2024-10-01 15:38:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用Python解决this optimization problem。我使用纸浆编写了以下代码:

import pulp
D = range(0, 10)
F = range(0, 10)
x = pulp.LpVariable.dicts("x", (D), 0, 1, pulp.LpInteger)
y = pulp.LpVariable.dicts("y", (F, D), 0, 1, pulp.LpInteger)
model = pulp.LpProblem("Scheduling", pulp.LpMaximize)
model += pulp.lpSum(x[d] for d in D)
for f in F:
    model += pulp.lpSum(y[f][d] for d in D) == 1
for d in D:
    model += x[d]*pulp.lpSum(y[f][d] for f in F) == 0
model.solve()

这里的最后一行返回:TypeError: Non-constant expressions cannot be multiplied。我知道它返回这个,因为它不能解决非线性优化问题。有没有可能把这个问题表述成一个适当的线性问题,这样就可以用纸浆来解决


Tags: 代码inimportformodelrangethis纸浆
1条回答
网友
1楼 · 发布于 2024-10-01 15:38:18

从数学模型开始总是一个好主意。你有:

  min sum(d, x[d])
  sum(d,y[f,d]) = 1   ∀f
  x[d]*sum(f,y[f,d]) = 0 ∀d
  x[d],y[f,d] ∈ {0,1} 

最后一个约束是非线性的(它是二次的)。这不能用纸浆来处理。该约束可以解释为:

  x[d] = 0 or sum(f,y[f,d]) = 0 ∀d

  x[d] = 1 ==> sum(f,y[f,d]) = 0 ∀d

这可以线性化为:

  sum(f,y[f,d]) <= (1-x[d])*M 

其中M = |F|(在F中的元素数,即|F|=10)。您可以检查:

 x[d]=0 => sum(f,y[f,d]) <= M (i.e. non-binding)
 x[d]=1 => sum(f,y[f,d]) <= 0 (i.e. zero)

所以你需要用这个线性约束代替二次约束

请注意,这不是唯一的公式。您还可以将单个项z[f,d]=x[d]*y[f,d]线性化。我把它作为练习

相关问题 更多 >

    热门问题