Reputation: 1181
Looking for a way to set up a constraint of my optimization problem using an IF ELSE function. It boils down to this: if constant A is smaller than variable B, then variable D=0, else D=A-B. Here's a clear formulation.
I get the error
TypeError: '>' not supported between instances of 'int' and 'LpVariable'
Is there a way to circumvent this?
My python script is shown below:
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] + '')
Upvotes: 1
Views: 1353
Reputation: 10059
you should try to find the equivalent of "if_then" that you have in docplex API
For instance
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)
gives
nbBus40 = 6.0
nbBus30 = 2.0
with if nb buses 40 more than 3 then nbBuses30 more than 7
nbBus40 = 0
nbBus30 = 10.0
Upvotes: 0
Reputation: 5930
I don't know PULP but what you are looking for are "indicator constraints" in CPLEX. Check the PULP documentation whether and how it supports indicator or logical constraints.
But there also is another option: Your problem is
minimize sum D(t)
D(t) = A(t)-B if A(t) > B
D(t) = 0 if A(t) <= B
Since this attempts to minimize D(t)
, in any optimal solution D(t)
will be as small as possible. So you can replace your constraints by
D(t) >= A(t) - B
D(t) >= 0
If B >= A(t)
then the first one will be trivially satisfied and the second one together with the objective sense will set D(t) = 0
. Similarly, if B < A(t)
then the second one will be trivially satisfied and the first one together with the objective sense will set D(t) = A(t) - B
.
Upvotes: 4