Obtaining Integer Values from Quicksum
AnsweredHi.
I have the following specification and would like to get the maximum value out of these 3.
I would like to store the maximum value as an integer value so that it can be used with a constraint (shown below).
The code I have is as follows:
x_ijs = grb_model.addVars(matches, vtype= GRB.BINARY, name="x_ijs")
for ca1sh in CA1SH:
minimum = ((ca1sh.min  quicksum(quicksum(x_ijs[i,j,s] for s in ca1sh.slots) for j in team_ids if i != j) for i in ca1sh.teams))
maximum = ((quicksum(quicksum(x_ijs[i,j,s]  ca1sh.max for s in ca1sh.slots) for j in team_ids if i != j) for i in ca1sh.teams))

Could you please share a minimal reproducible example where you use Gurobi's buildin max function? I don't see a particular reason why using it would not work.
Best regards,
Jaromił1 
My code is as follows:
And this is the error that is being displayed. Should maximum and minimum be set to some sort of Gurobi variable?
Code in a code block:
for ca1sh in CA1SH:
minimum = ((ca1sh.min  quicksum(quicksum(x_ijs[i,j,s] for s in ca1sh.slots) for j in team_ids if i != j) for i in ca1sh.teams))
maximum = ((quicksum(quicksum(x_ijs[i,j,s]  ca1sh.max for s in ca1sh.slots) for j in team_ids if i != j) for i in ca1sh.teams))
max_val = grb_model.addGenConstrMax(minimum, maximum, 0)
print(max_val)0 
You have to follow the definition of the addGenConstrMax method. The arguments you provide are incorrect and you should try
grb_model.addGenConstrMax(max_val, [minimum,maximum], constant=0, name="maxconstr")
The above generates the constraint
\[\text{max_val} = \max(\text{minimum}, \text{maximum}, 0) \]
Best regards,
Jaromił0 
Hi.
Thanks for the quick reply. How should I instantiate the max_val variable? What type of Gurobi variable should it be set to?
Regards
0 
As described in the documentation of the addGenConstrMax method, \(\texttt{max_val}\) has to be a Var object.
0 
Hi.
I now face this error.
It is worth mentioning that x_ijs is a GRB.BINARY variable type.
0 
Please have a closer look at the documentation of the addGenConstrMax method.
The objects \(\texttt{maximum,minimum}\) both have to be Var objects as well. Thus, you have to introduce equality constraints stating
# define optimization variables minimum, maximum
minimum = grb_model.addVar(lb=GRB.INFINITY)
maximum = grb_model.addVar(lb=GRB.INFINITY)
# add constraints minimum = ... and maximum = ...
grb_model.addConstr(minimum == ((ca1sh.min  quicksum(...)))
grb_model.addConstr(maximum == ...)0 
Hi.
Thanks again. When calculating the following:
quicksum(quicksum(x_ijs[i,j,s] for s in ca1sh.slots) for j in team_ids if i != j) for ca1sh in CA1SH for i in ca1sh.teamsthe result is being generated as a generator object.Any ideas?0 
The quicksum function returns an expression object and not a list. Thus, you cannot use a quicksum result as input argument for the quicksum function. This is not a problem, because you can use multiple \(\texttt{for}\)loops in one quicksum:
quicksum(x_ijs[i,j,s] for s in ca1sh.slots for j in team_ids if i != j for ca1sh in CA1SH for i in ca1sh.teams)
0 
Hi. Regarding this issue, when I am trying to retrieve the value by updating the model (i.e. max_val.Obj), the value is always 0. Below is a code sample.
I am using 2 models in one program because if I use the same model (grb_model), I would not be able to retrieve certain values and the model is not optimised. Also, is there a way in which I can merge the two constraints in the original post into one?
Thanks Oleg
for i in team_ids:
for ca1sh in CA1SH:
dev_model.addConstr(minimum == (ca1sh.min  quicksum(x_ijs[i,j,s] forsinca1sh.slots forjinca1sh.teams ifi != j)))
dev_model.addConstr(maximum == (quicksum(x_ijs[i,j,s] forsinca1sh.slots forjinca1sh.teams ifi != j)  ca1sh.max))
calc_max = dev_model.addGenConstrMax(max_val, [minimum, maximum], constant = 0)
dev_model.update()
maxi_val = max_val.Obj
print(maxi_val)0 
To access the objective value, you have to access the ObjVal attribute of the model object, i.e.,
maxi_val = dev_model.ObjVal
Note that the update method does not change any solution values. It propagates all model changes but it does not resolve the model. To get a new objective value after changing the objective function, you have to call the optimize method before accessing the ObjVal attribute.
dev_model.addConstr(minimum == (ca1sh.min  quicksum(x_ijs[i,j,s] forsinca1sh.slots forjinca1sh.teams ifi != j)))
dev_model.addConstr(maximum == (quicksum(x_ijs[i,j,s] forsinca1sh.slots forjinca1sh.teams ifi != j)  ca1sh.max))
calc_max = dev_model.addGenConstrMax(max_val, [minimum, maximum], constant = 0)
dev_model.update()
dev_model.optimize()
maxi_val = dev_model.ObjValPlease also note that you should check the Status attribute before accessing any solution information, cf. mip2.py example (unless you are 100% sure that the model is always feasible).
0 
I am still not sure about this. Is there a way to combine both constraints into one?
0 
Not directly. However, you can access the LinExpr objects describing the lhs of the constraints and add them together. You also have to to this for the RHS of each constraint.
import gurobipy as gp
m = gp.Model("test")
x = m.addVar()
y = m.addVar()
c1 = m.addConstr(x + y <= 3)
c2 = m.addConstr(2*x  0.5*y <= 0.1)
m.update()
# get lhs of each constraint
linexprc1 = m.getRow(c1)
linexprc2 = m.getRow(c2)
# construct a new constraint by adding the lhs and rhs
m.addConstr( linexprc1 + linexprc2 <= c1.rhs + c2.rhs)
# write LP file to check the result
m.write("myLP.lp")Note that most often, combining constraints only makes sense if they have the same sense (\(\leq, \geq, =\).
0 
Thanks for your quick response. I wanted to ask, is it possible to use a max_ function in a constraint and store it? (See below)
grb_model.addConstrs((quicksum(x[i,j,k]  ca1sh.max for j in ca1sh.teams for k in ca1sh.slots if i != j) <= max_(..., constant = 0) for i in team_ids for ca1sh in CA1SH), "Constraint 4.13")
Thanks, Oleg
0 
It is not possible to use the \(\texttt{max_}\) function directly in a constraint, cf. documentation of the max function. You have to define an auxiliary variable and equality constraint to model
m.addConstr(aux == max_(...,constant))
# use aux as max_(...,constant)Could you explain what exactly you mean by store?
0 
Storing it in a variable as you mentioned. Thanks for now.
0 
I have a question. Can you have constraints in a model which they should not be considered when optimising the model but need such constraints to obtain certain values? For example, getting the maximum value.
0 
Can you have constraints in a model which they should not be considered when optimising the model but need such constraints to obtain certain values?
Yes, redundant constraints are fine and will most likely be removed during presolve. You can still access the value of all variables/constraints after a successful optimization run even if the constraints/variables are redundant.
0 
How would such constraints be instantiated?
0 
You just add it as a regular constraint. For example
import gurobipy as gp
m = gp.Model("test")
x = m.addVar()
y = m.addVar()
c1 = m.addConstr(x >= 3)
c2 = m.addConstr(y == 4*x)
m.setObjective(x)
m.optimize()
print(y.X)Constraint \(\texttt{c2}\) and variable \(y\) do not affect the model at all, but through the solution value of \(y\) and constraint \(\texttt{c2}\), I am able to easily access the value of \(4\cdot x\). Note that while it may be convenient, adding an excessive amount of redundant constraint may slow down the optimization process significantly. Thus, it is best to compute specific values of interest manually using optimal solution point values, after the optimization process has been performed.
0
Please sign in to leave a comment.
Comments
20 comments