使用 PulP 进行 LP 优化。使用 IF 设置约束
LP Optimization with PulP. Using IF to set up constraints
正在寻找一种使用 IF ELSE 函数为我的优化问题设置约束的方法。归结为:如果常量 A 小于变量 B,则变量 D=0,否则 D=A-B。这里是 a clear formulation.
我收到错误
TypeError: '>' not supported between instances of 'int' and 'LpVariable'
有什么办法可以避免这种情况吗?
我的python脚本如下所示:
import pulp
import random
# setting up constants
t_0=1000
A=[]
for x in range(t_0):
A.append(random.randint(1,10))
# initializing LP
LP = pulp.LpProblem('LP',pulp.LpMinimize)
# adding variables
B = pulp.LpVariable("B", cat='Continuous', lowBound=0)
D = pulp.LpVariable.dicts("D", range(t_0), cat=pulp.LpContinuous, lowBound=0)
# adding constraints
for t in range(t_0):
if A[t] > B:
LP += D[t] == A[t] - B
else:
LP += D[t] == 0
LP += pulp.lpSum(D[t] for t in range(t_0))
status = LP.solve(pulp.CPLEX_PY(mip=True, msg=True, timeLimit=15,epgap=None))
print( 'LP status: ' + pulp.LpStatus[status] + '')
我不知道 PULP,但您正在寻找的是 CPLEX 中的 "indicator constraints"。检查 PULP 文档是否以及如何支持指标或逻辑约束。
不过还有一个选择:你的问题是
minimize sum D(t)
D(t) = A(t)-B if A(t) > B
D(t) = 0 if A(t) <= B
因为这试图最小化 D(t)
,在任何最优解中 D(t)
将尽可能小。所以你可以用
替换你的约束
D(t) >= A(t) - B
D(t) >= 0
如果 B >= A(t)
则第一个将微不足道地满足,第二个与 objective 一起将设置 D(t) = 0
。类似地,如果 B < A(t)
那么第二个将很容易满足,第一个与 objective 一起将设置 D(t) = A(t) - B
.
你应该尝试找到你在 docplex API
中的 "if_then" 的等价物
例如
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
print()
print("with if nb buses 40 more than 3 then nbBuses30 more than 7")
mdl.add(mdl.if_then((nbbus40>=3),(nbbus30>=7)))
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
给予
nbBus40 = 6.0
nbBus30 = 2.0
with if nb buses 40 more than 3 then nbBuses30 more than 7
nbBus40 = 0
nbBus30 = 10.0
正在寻找一种使用 IF ELSE 函数为我的优化问题设置约束的方法。归结为:如果常量 A 小于变量 B,则变量 D=0,否则 D=A-B。这里是 a clear formulation.
我收到错误
TypeError: '>' not supported between instances of 'int' and 'LpVariable'
有什么办法可以避免这种情况吗?
我的python脚本如下所示:
import pulp
import random
# setting up constants
t_0=1000
A=[]
for x in range(t_0):
A.append(random.randint(1,10))
# initializing LP
LP = pulp.LpProblem('LP',pulp.LpMinimize)
# adding variables
B = pulp.LpVariable("B", cat='Continuous', lowBound=0)
D = pulp.LpVariable.dicts("D", range(t_0), cat=pulp.LpContinuous, lowBound=0)
# adding constraints
for t in range(t_0):
if A[t] > B:
LP += D[t] == A[t] - B
else:
LP += D[t] == 0
LP += pulp.lpSum(D[t] for t in range(t_0))
status = LP.solve(pulp.CPLEX_PY(mip=True, msg=True, timeLimit=15,epgap=None))
print( 'LP status: ' + pulp.LpStatus[status] + '')
我不知道 PULP,但您正在寻找的是 CPLEX 中的 "indicator constraints"。检查 PULP 文档是否以及如何支持指标或逻辑约束。
不过还有一个选择:你的问题是
minimize sum D(t)
D(t) = A(t)-B if A(t) > B
D(t) = 0 if A(t) <= B
因为这试图最小化 D(t)
,在任何最优解中 D(t)
将尽可能小。所以你可以用
D(t) >= A(t) - B
D(t) >= 0
如果 B >= A(t)
则第一个将微不足道地满足,第二个与 objective 一起将设置 D(t) = 0
。类似地,如果 B < A(t)
那么第二个将很容易满足,第一个与 objective 一起将设置 D(t) = A(t) - B
.
你应该尝试找到你在 docplex API
中的 "if_then" 的等价物例如
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
print()
print("with if nb buses 40 more than 3 then nbBuses30 more than 7")
mdl.add(mdl.if_then((nbbus40>=3),(nbbus30>=7)))
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
给予
nbBus40 = 6.0
nbBus30 = 2.0
with if nb buses 40 more than 3 then nbBuses30 more than 7
nbBus40 = 0
nbBus30 = 10.0