cheesus
cheesus

Reputation: 1181

LP Optimization with PulP. Using IF to set up constraints

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

Answers (2)

Alex Fleischer
Alex Fleischer

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

Daniel Junglas
Daniel Junglas

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

Related Questions