使用PulP进行LP优化。使用IF设置约束

时间:2019-07-25 22:51:12

标签: python mathematical-optimization linear-programming cplex pulp

寻找一种使用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] + '')

2 个答案:

答案 0 :(得分:2)

我不了解PULP,但是您正在寻找的是CPLEX中的“指标约束”。检查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),那么第一个将是微不足道的,而第二个将与客观意义一起设置为D(t) = 0。类似地,如果B < A(t),那么第二个将是微不足道的,第一个连同客观意义将设置为D(t) = A(t) - B

答案 1 :(得分:0)

您应该尝试查找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