coin-or / pulp

A python Linear Programming API
http://coin-or.github.io/pulp/
Other
2.11k stars 387 forks source link

Using modulus operator in Constraint #762

Open rogeriobiondi opened 4 months ago

rogeriobiondi commented 4 months ago

What is your question

Hello, is it possible using the modulus operator in a constraint?

For example

q1 = pulp.LpVariable(name = 'q1', lowBound=100, cat='Integer')
Z += (q1 % 100) == 0

I'm getting an invalid operator:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[39], line 25
---> 25 Z += q1 % 100 == 0

TypeError: unsupported operand type(s) for %: 'LpVariable' and 'int'

I would want that the variable q1 would be a multiple of 100.

Thank you very much.

Alannikos commented 2 months ago

hi, i also met the error, did you find the solution? @rogeriobiondi

urbanophile commented 2 months ago

No, pulp doesn't allow the use of modulo operator % in constraint like that.

Modulo is not linear function, so in some ways this is the expected response for a linear programming model. Since x is an integer, though, you can represent a modulo constraint by introducing a new variable q so that x - q*100 == 0, like so:

>>> from pulp import *
>>> x = LpVariable("x", 100, 200, cat="Integer")
>>> y = LpVariable("y", 100, 200, cat="Integer")
>>> prob = LpProblem("moduloExample", LpMaximize)
>>> prob += x+y<=399
>>> modulus = 100
>>> q = LpVariable("q",0,modulus-1, "Integer") # helper variable
>>> prob += x - modulus * q == 0
>>> status = prob.solve(PULP_CBC_CMD(msg=0))
>>> LpStatus[status]
1

>>> value(x)
100.0

>>> value(y)
100.0

>>> value(q)
1.0
rogeriobiondi commented 2 months ago

After studying a little in the OR books, I found this exact reason: the possible solution space will be bounded by the restrictions, and they must be all linear equations. So I had to rethink the problem and adapt it to the technique.