2

I have to solve an integer linear optimization problem in Python with pulp. I solved the basic problem and now I have to add additional constraints. Is anybody who can help me with adding the condition with a logical indicator? The logical restriction is: B>5 if A>20

Here is my code:

from pulp import *

prob = LpProblem("The Optimization Problem", LpMaximize)
A = LpVariable("A", 0, 100)
B = LpVariable("B", 0, 200)
C = LpVariable("C", 0, 100)
R1 = LpVariable("R1", 0)
R2 = LpVariable("R2", 0)

R1 = 0.1 * A + 0.2 * B + 0.075 * C
R2 = 0.05 * A + 0.1 * B + 0.05 * C

prob += 2 * A + 3 * B + 2.55 * C - 0.6 * R1 - 0.8 * R2
prob += 0.5 * A + 0.8 * B + C <= 100, "T1"
prob += 0.8 * A + 0.6 * B + 0.2 * C <= 100, "T2"


prob.writeLP("OptimizationModel.lp")

prob.solve()
print("Status:", LpStatus[prob.status])
for v in prob.variables():
    print(v.name, "=", v.varValue)
patii
  • 21
  • 1
  • 2
  • Possible duplicate of [How to add Logical constraints in PuLP](https://stackoverflow.com/questions/33360898/how-to-add-logical-constraints-in-pulp) – Asdrubal Jan 16 '18 at 19:16
  • could you please verify if I thinking correctly? I've put variable f: `f = LpVariable('f', cat="binary")` and I have added the conditions: `prob += A - 20 <= f * 5, prob += B >= f` is it ok? – patii Jan 16 '18 at 21:41
  • Obviously not as you want B >= 5 and not B >= f = 0/1. Furthermore you will need some bigM-like-constant. – sascha Jan 16 '18 at 21:46
  • ok, but I have to consider the lower boundary of B. I have changed the f initialize function `f = LpVariable('f',0,1,cat='Integer')` and the code `prob += A - 20 <= f * M, prob += B >= f*5` but I still don't know if the code is correct. – patii Jan 16 '18 at 22:16

1 Answers1

2

I think you are on the right track with creating a binary 'on-off' variable in f.

f = LpVariable('f',0,1,cat='Integer')

If I understand correctly, you need B to be > 5 as long as A is > 20, right?

Then what you need is to tweak your code such f is set to 1 as long as A is more than 20.

Since f is binary, you can do this:

prob+= f>= (A-20)/80
prob+= B>= 6*f

In the first line, (A-20)/80 will be negative for values of A from 0 to 19, and will be zero when A is 20. This will ensure that f is zero for these values of A.

When f is zero, the second constraint just implies B has to be at least zero, which is its lower bound anyway.

If, however, A is 21 and above ie A>20, then (A-20)/80 becomes positive, but never greater than 1 (more on this later). This then forces f to be at least 1 whenever A is 21 and above. Since f can only be 1 or 0, f then is set to 1.

This will result in the second constraint forcing B to at least 6 whenever B is 1, which is whenever A is greater than 20. In short, B is more than 5 whenever f is 1, which is whenever A is greater than 20.

Hope this helps! Please let me know if it doesn't work. I've been working on a puLP problem myself, and used this method to write a few of my constraints.

Note: We divide by 81 to ensure that (A-20)/80 always never bigger than one. for example, if A is 21, then (A-20)/80 evaluates to 1/80. Since A can only be as large as 100, then (A-20)/80 can therefore only ever be as large As (100-20)/80 ie 1. If we changed it to (A-20)/X, where X here is any other value below the largest value of (A-20), then the fraction (A-20)/X can be more than 1. And since f is binary (1 or 0), then the constraint f>= (A-20)/X would mean we would actually be forcing A to be smaller than it would be otherwise.

rnshwn
  • 65
  • 7