如何在 Python 上使用 PuLP GLPK 为混合整数线性规划 (MILP) 的决策变量编写 IF 条件?
How can I write an IF condition for my decision variable for Mixed Integer Linear Programming (MILP) using PuLP GLPK on Python?
我正在尝试在 Python 上使用 GLPK 求解器在 PuLP 上使用混合整数线性规划来解决优化问题。到目前为止,我已经成功地解决了带有约束的基本优化问题,例如:
prob = LpProblem("MILP", LpMinimize)
x1 = LpVariable("x1",lowBound=0, cat = 'Binary')
x2 = LpVariable("x2", cat = 'Continuous')
prob += 4*x1 + x2, "Objective Function"
prob += x2 - 4*x1 <= 0
prob += x2 - 2*x1 >= 0
status = prob.solve()
LpStatus[status]
value(x1), value(x2), value(prob.objective)
这给出了最佳结果,其中 x1 = 1.0,x2 = 3.0 且 Objective 函数 = 7.0
我想弄清楚的是如何解决具有 if 条件的优化问题,例如,以下约束:
x1 > 0 IF x2 > 2
或类似的东西:
x1 > 0 IF x2 == 3
基本上,如何将 if 条件语句集成到 MILP 约束中。
欢迎来到 SO!您要查找的 google 搜索词是 "indicator variable" 或 "big-M constraint".
据我所知,PULP 不直接支持指标变量,因此大 M 约束是可行的方法。
一个简单的例子:
x1 <= 0 IF x2 > 2
from pulp import *
prob = LpProblem("MILP", LpMaximize)
x1 = LpVariable("x1", lowBound=0, upBound=10, cat = 'Continuous')
x2 = LpVariable("x2", lowBound=0, upBound=10, cat = 'Continuous')
prob += 0.5*x1 + x2, "Objective Function"
b1 = LpVariable("b1", cat='Binary')
M1 = 1e6
prob += b1 >= (x1 - 2)/M1
M2 = 1e3
prob += x2 <= M2*(1 - b1)
status = prob.solve()
print(LpStatus[status])
print(x1.varValue, x2.varValue, b1.varValue, pulp.value(prob.objective))
我们希望约束 x1 <= 0
在 x2 > 2
时存在。当 x2 <= 2
不存在此类约束时(x1
可以是正数或负数)。
首先我们创建一个二进制变量:
b1 = LpVariable("b1", cat='Binary')
选择这个代表条件x2 > 2
。实现此添加约束的最简单方法:
M1 = 1e6
prob += b1 >= (x2 - 2)/M1
这里M1
是大M值。需要选择它使得 x2
的最大可能值表达式 (x2-2)/M
是 <=1
。它应该尽可能小以避免 numerical/scaling 问题。这里的值 10 会起作用(x2
的上限为 10)。
要了解此约束的工作原理,请考虑以下情况,对于 x2<=2,右侧至多为 0,因此无效(二进制变量的下限已设置为 0 ).但是,如果 x2>2
右侧将强制 b1
大于 0 - 作为二进制变量,它将被强制为 1.
最后,我们需要构建所需的约束:
M2 = 1e3
prob += x1 <= M2*(b1 - 1)
再次了解此约束的工作原理,考虑以下情况,如果 b1 为真 (1
),则约束处于活动状态并变为:x1 <= 0
。如果 b1 为假('0'),则约束变为 x1 <= M2
,前提是 M2
足够大,这将不起作用(这里它可以小到 10,因为 x1
已经有一个10 的上限。
在上面的完整代码中,如果您在 objective 函数中改变 x1
的系数,您应该注意到 b1
是 activated/de-activated 并且附加约束应用于x1
符合预期。
我正在尝试在 Python 上使用 GLPK 求解器在 PuLP 上使用混合整数线性规划来解决优化问题。到目前为止,我已经成功地解决了带有约束的基本优化问题,例如:
prob = LpProblem("MILP", LpMinimize)
x1 = LpVariable("x1",lowBound=0, cat = 'Binary')
x2 = LpVariable("x2", cat = 'Continuous')
prob += 4*x1 + x2, "Objective Function"
prob += x2 - 4*x1 <= 0
prob += x2 - 2*x1 >= 0
status = prob.solve()
LpStatus[status]
value(x1), value(x2), value(prob.objective)
这给出了最佳结果,其中 x1 = 1.0,x2 = 3.0 且 Objective 函数 = 7.0
我想弄清楚的是如何解决具有 if 条件的优化问题,例如,以下约束:
x1 > 0 IF x2 > 2
或类似的东西:
x1 > 0 IF x2 == 3
基本上,如何将 if 条件语句集成到 MILP 约束中。
欢迎来到 SO!您要查找的 google 搜索词是 "indicator variable" 或 "big-M constraint".
据我所知,PULP 不直接支持指标变量,因此大 M 约束是可行的方法。
一个简单的例子:
x1 <= 0 IF x2 > 2
from pulp import *
prob = LpProblem("MILP", LpMaximize)
x1 = LpVariable("x1", lowBound=0, upBound=10, cat = 'Continuous')
x2 = LpVariable("x2", lowBound=0, upBound=10, cat = 'Continuous')
prob += 0.5*x1 + x2, "Objective Function"
b1 = LpVariable("b1", cat='Binary')
M1 = 1e6
prob += b1 >= (x1 - 2)/M1
M2 = 1e3
prob += x2 <= M2*(1 - b1)
status = prob.solve()
print(LpStatus[status])
print(x1.varValue, x2.varValue, b1.varValue, pulp.value(prob.objective))
我们希望约束 x1 <= 0
在 x2 > 2
时存在。当 x2 <= 2
不存在此类约束时(x1
可以是正数或负数)。
首先我们创建一个二进制变量:
b1 = LpVariable("b1", cat='Binary')
选择这个代表条件x2 > 2
。实现此添加约束的最简单方法:
M1 = 1e6
prob += b1 >= (x2 - 2)/M1
这里M1
是大M值。需要选择它使得 x2
的最大可能值表达式 (x2-2)/M
是 <=1
。它应该尽可能小以避免 numerical/scaling 问题。这里的值 10 会起作用(x2
的上限为 10)。
要了解此约束的工作原理,请考虑以下情况,对于 x2<=2,右侧至多为 0,因此无效(二进制变量的下限已设置为 0 ).但是,如果 x2>2
右侧将强制 b1
大于 0 - 作为二进制变量,它将被强制为 1.
最后,我们需要构建所需的约束:
M2 = 1e3
prob += x1 <= M2*(b1 - 1)
再次了解此约束的工作原理,考虑以下情况,如果 b1 为真 (1
),则约束处于活动状态并变为:x1 <= 0
。如果 b1 为假('0'),则约束变为 x1 <= M2
,前提是 M2
足够大,这将不起作用(这里它可以小到 10,因为 x1
已经有一个10 的上限。
在上面的完整代码中,如果您在 objective 函数中改变 x1
的系数,您应该注意到 b1
是 activated/de-activated 并且附加约束应用于x1
符合预期。