Is there a way to introduce a rounding constraint, something on the following lines : v = floor(x * y)
, where x, y
are continuous decision variables and v
is an integer decision variable. Essentially want to cast multiplication of continuous decision variable to integer. I am using Gurobi solver.
Above can be achieved by adding following inequality constraints:
v <= x*y <= v + 1
With help of above inequalities, v
would be rounded down to the value of x*y
. This would work perfectly if x*y
is a float, however, if x*y
is an integer say, 6, then v
could be either be 5 or 6. To avoid such cases, one could introduce a small constant tolerance e > 0
and apply it to one of the inequalities.
Below is a short code snippet to demonstrate the above reasoning:
import gurobipy as gp
from gurobipy import GRB
m = gp.Model()
x = m.addVar(vtype = GRB.CONTINUOUS, ub = 5)
y = m.addVar(vtype = GRB.CONTINUOUS, ub = 8)
int_var = m.addVar(vtype = GRB.INTEGER)
# fix x, y to some float values.
# x*y = 27.8695, so int_var should = 27, post solve
m.addConstr(x == 4.01)
m.addConstr(y == 6.95)
e = 0.00001
m.addConstr(x*y >= int_var - e)
m.addConstr(x*y <= int_var + 1 - e)
# dummy objective, since x and y are already fixed
m.setObjective(x*y, sense = GRB.MAXIMIZE)
m.optimize()
Indeed, int_var
resolves to 27
which is the floor of x*y = 27.8695
.
If you take x*y=24
, the int_var
will resolve to 24
(which is expected behaviour, per small tolerance e
taken above.