【问题标题】:Using multiplication in a pulp constraint在纸浆约束中使用乘法
【发布时间】:2022-11-17 05:59:04
【问题描述】:

我正在尝试解决与这个更简单的示例类似的问题。

Target Constraint
12 25
15 50
14 10
8 2

ETC

我正在尝试最大化目标列选择的总和,同时保持约束列的乘积 < 某个数字。因此,例如,如果约束为 500,则一种可能的解决方案为 34,另一种为 29。

我将如何编写该约束?

【问题讨论】:

  • 你的例子不清楚。你能编辑你的帖子并提供一个更完整的例子吗?变量是什么?什么是“约束列的乘积”? 34 与 500 有什么关系?
  • 在这个例子中,我可以选择 12、14 和 8(总共 34),因为 25*10*2 = 500。同样,我也可以选择 15、14(总共 29),因为 50*10 = 500。我不能选择 12、15(总共 27),因为 25*50 > 500。
  • 知道了。所以你有二进制“选择”变量和“目标”是可选的。您所描述的构造是非线性的,因为您在约束中使用了变量的乘积,因此您可能需要将框架转移到处理 NLP 的框架,而 pulp 则不需要。您的约束类似于: (x1*t1)(x2*t2)... <= 500 其中 x 是二进制变量,t 是目标值。由于 x 的乘法,该构造是非线性的

标签: python pulp


【解决方案1】:

正如@AirSquid 指出的那样,变量的乘法在线性程序的目标或约束中是不允许的(这会使它成为非线性的)。

但是,您所描述的问题可以通过记录日志来直接和精确地线性化。一些数字乘积的对数等于这些数字的对数之和。像这样的东西:

import pulp
import numpy as np

targets = [12, 15, 14, 8]
constrs = [25, 50, 10, 2]
max_prod = 500
row_idxs = range(len(targets))

log_constrs = [np.log(i) for i in constrs]
log_max_prod = np.log(max_prod)

prob = pulp.LpProblem('so_74304315', pulp.LpMaximize)
z = pulp.LpVariable.dicts('z', indexs=row_idxs, cat='Binary')

# Objective
prob += pulp.lpSum([targets[i]*z[i] for i in row_idxs])

# Constraint (linearised from product to sum of logs)
prob += pulp.lpSum([log_constrs[i]*z[i] for i in row_idxs]) <= log_max_prod

# Solve & print results:
prob.solve()
print("Status:", pulp.LpStatus[prob.status])
print("Objective value: ", pulp.value(prob.objective))
print ("Decision variables: ")
for v in prob.variables():
    print(v.name, "=", v.varValue)

这给了我:

Status: Optimal
Objective value:  34.0
Decision variables:
z_0 = 1.0
z_1 = 0.0
z_2 = 1.0
z_3 = 1.0

【讨论】:

    猜你喜欢
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多