paleoantropos
paleoantropos

Reputation: 21

How to add conditional constraints to a linear optimisation model in PuLP

I'm new to PuLP and linear programming. I know that there are already some questions about conditional constraints but I just can't wrap my head around it and implement my problem in a linear optimisation model correctly. Basically, I got a variable x which can take any value between -10 and 10. Now, I want to know if it is positiv or negativ and depending on that change other variables. So something like:

T = 7
x = np.random.randint(-10,10,T)
x1 = np.empty(len(T))
x2 = np.empty(len(T))

for i in range(len(T)):
    if x[i] >= 0:
        x1[i] = x[i]
        x2[i] = 0
    else:
        x2[i] = x[i]
        x1[i] = 0

I tried to use the big M method to implement it like this:

model = LpProblem("min_prob", LpMinimize)

T = 7 # random length as an example
M = 10

# create variables
x = [LpVariable('x_{}'.format(i), None, None) for i in range(T)]
x1 = [LpVariable('x1_{}'.format(i), 0, None) for i in range(T)]
x2 = [LpVariable('x2_{}'.format(i), None, 0) for i in range(T)]

#create binary variables
y1 = [LpVariable('y1_{}'.format(i), cat='Binary') for i in range(T)]
y2 = [LpVariable('y1_{}'.format(i), cat='Binary') for i in range(T)]

for i in range(T):
    model += x[i] == np.random.randint(-10,10,T)
    model += x[i] <= (1-y1[i])*M # y1 = 0 if x is positiv
    model += x[i] >= -(1-y2[i])*M # y2 = 0 if x is negative
    model += y1[i] + y2[i] <= 1
    
    model += x1[i] == x[i] * y2[i]
    model += x2[i] == x[i] * y1[i]

But I realised that pulp can not multiple two variables because the problem might become non-linear.

Could anybody show me how to correctly implement this? Thank you for your help!

Upvotes: 2

Views: 503

Answers (1)

Erwin Kalvelagen
Erwin Kalvelagen

Reputation: 16724

Let's forget initially about Python and Pulp and focus on the math. (Putzing around with code without understanding the underlying math is usually not a good idea).

We want:

if x[i] >= 0 then
    x1[i] = x[i]
    x2[i] = 0
if x[i] <= 0 then
    x2[i] = x[i]
    x1[i] = 0

Often, we write this a little bit more succinctly as:

x1[i] := max(0,x[i])
x2[i] := min(0,x[i])

We can write this as:

x1[i]+x2[i] = x[i]
x1[i] = 0 or x2[i] = 0
x1[i] >= 0
x2[i] <= 0

This leads to:

x1[i]+x2[i] = x[i]
x1[i] <= b[i]*M
x2[i] >= -(1-b[i])*M
b[i] ∈ {0,1}
x1[i] >= 0
x2[i] <= 0     

Upvotes: 3

Related Questions