Nested quicksum
AnsweredDear community,
I am struggling with the quicksum function while trying to fomulate the following formula in python:

How do I write this by using quicksum()? I tried it that way:
import gurobipy as gp
gp.quicksum( gp.quicksum( gp.quicksum( a[j,k] * b[i,j] for k in set_K ) + gp.quicksum( c[i,j,k] * d[i,j] for k in set_K ) for j in set_J ) for i in set_I )
Is that correct? Thanks for your help!
-
Hi DR,
gurobipy.quicksum takes exactly one argument, and that argument should be an iterable such as a list, tuple or generator expression. You can use a generator expression like so:
gp.quicksum(a[j,k]*b[i,j] + c[i,j,k]*d[i,j] for i in set_I for j in set_J for k in set_K)
or alternatively using itertools
import itertools
gp.quicksum(a[j,k]*b[i,j] + c[i,j,k]*d[i,j] for i,j,k in itertools.product(set_I, set_J, set_K))It may help your understanding to write these generator expressions as list comprehensions so you can understand what is being given as an argument to gp.quicksum.
- Riley
0 -
Thanks, Riley! Is it also possible to write such expressions with the groupby function from the gurobipy_pandas package?
0 -
Hi DR,
You should be able to use gurobipy-pandas here. Note that with the exception of b and d, the variables have different indices and would be associated with different dataframes. As an example consider the following code
import pandas as pd
import gurobipy as gp
from gurobipy import GRB
import gurobipy_pandas as gppd
import itertools
a_df = pd.DataFrame(
index = pd.MultiIndex.from_tuples(itertools.product(range(3), range(4)), names=["j", "k"])
)
b_df = pd.DataFrame(
index = pd.MultiIndex.from_tuples(itertools.product(range(2), range(3)), names=["i", "j"])
)
model = gp.Model()
model.ModelSense = GRB.MAXIMIZE
a = gppd.add_vars(model, a_df, vtype=GRB.BINARY, name="a")
b = gppd.add_vars(model, b_df, vtype=GRB.BINARY, name="b")
model.update()The following sum (in the style of your original model):
gp.quicksum(a[j,k]*b[i,j] for i,j,k in itertools.product(range(2), range(3), range(4)))
is equivalent to
(a*b).sum()
using gurobipy-pandas.
The groupby is only needed if creating multiple constraints of the same form at the same time, which is not the case for your quicksum expression.
- Riley1
Please sign in to leave a comment.
Comments
3 comments