Can you round PuLP variables before solving the problem or get around this issue?

419 views Asked by At

I am trying to optimize purchase orders from multiple factories. My required quantities are set. I can solve the problem easily while obeying the capacities of each factory except that it assigns production of items to factories that makes for partial containers when shipping them. As a company policy, we do not order partial containers. It is also near impossible to get exact containers so I wanted to make sure that if we are ordering from a factory, all containers containing product needs to be 99% full and wrote the following PuLP constraint:

for f in factory:
    model += (lp.lpSum([m3.loc[i,f] * qty[i,f]] for i in items) / m3_per_container) / \
        math.ceil(lp.lpSum([m3.loc[i,f] * qty[i,f]] for i in items) / m3_per_container) * M) \
            >= 0.99

However when I run the problem with this constraint, I get this error:

TypeError: must be real number, not LpAffineExpression

I am guessing, it's because I cannot round an LpVariable up to the nearest higher integer before I solve the problem and assign it a value first.

Does anyone have a way of achieving the goal of making sure the order placed at a factory makes for containers between the multiples of .99 (0.99, 1.98, 2.97, etc.) and multiples of 1 (1, 2, 3, etc.) without running into this error?

Thanks in advance!

1

There are 1 answers

0
Erwin Kalvelagen On

You can simulate a ceiling function in a MIP model as follows:

 y=ceil(x)

is approximately equivalent to

 y >= x
 y <= x+0.999
 y integer

I typically use 1 instead of 0.999 and let the solver pick the best if x is already exactly integer-valued.