Different solutions for different modelling approaches
AnsweredHey,
I obtain different solutions for different modelling approaches:
1.) Approach
factor_obj_c = {
c: m.addVar(name=f"factor_obj_{c}") for c in C
}
quad_expr_c = {
c: m.addVar(name=f"quad_expr_{c}") for c in C
}
sum_binary_c = {
c: m.addVar(name=f"sum_bin_{c}") for c in C
}
m.setObjective((1 / C) * gp.quicksum(factor_obj_c[c] for c in C), GRB.MINIMIZE)
for c in C:
m.addConstr(
sum_binary_c[c] == gp.quicksum(z_c_r[c, r] for r in R_c[c])
)
m.addQConstr(
quad_expr_c[c] == gp.quicksum(z_c_r[c, r] * mu_c_r[c, r] for r in R_c[c])
)
m.addQConstr(
quad_expr_c[c] == sum_binary_c[c] * factor_obj_c[c]
)
Please note here that C is some set and R_c some dict which can be accessed through key c. Also one this I should mention is that for my example C = {1} so that we can formulate quad_expr_c in the following as a onedimensional decision variable (in the example below we refer to quad_expr). The solution approach above returns the wrong solution compared to the situation where I make the following change:
2.) Approach (correct solution)
factor_obj = {
c: m.addVar(name=f"factor_obj_{c}") for c in C
}
quad_expr = m.addVar(1)
m.setObjective((1 / C) * gp.quicksum(factor_obj[c]
for c in C), GRB.MINIMIZE)
for c in C:
m.addConstr(
quad_expr == gp.quicksum(z_c_r[c, r] * mu_c_r[c, r]
for r in R_c[c])
)
m.addConstr(
gp.quicksum(z_c_r[c, r] for r in R_c[c]) * factor_obj[c] ==
quad_expr
)
Very grateful for support here!
Best
Paul

Hi Paul,
Could you please provide a minimal reproducible example of both formulations? You can use the write method to generate humanreadable LP files by calling
model.write("myModel.lp")
You can open the file \(\texttt{myModel.lp}\) in any standard text editor to analyze whether the formulations who are comparing are indeed equivalent.
Best regards,
Jaromił0 
Jaromił Najman thanks for the response! I was actually able to solve the problem by myself with introducing a support variable (support_quad_expr):
factor_obj = {
c: m.addVar(name=f"factor_obj_{c}") for c in C
}
support_quad_expr = m.addVar(1)
quad_expr_c = {
c: m.addVar(name=f"quad_expr_{c}") for c in C
}m.setObjective((1 / C) * gp.quicksum(factor_obj[c]
for c in C), GRB.MINIMIZE)
for c in C:
m.addConstr(
quad_expr_c[c] == gp.quicksum(z_c_r[c, r] * mu_c_r[c, r] for r in R_c[c])
)
m.addConstr(
quad_expr_c[c] == support_quad_expr
)
m.addConstr(
gp.quicksum(z_c_r[c, r] for r in R_c[c]) * factor_obj[c]
== support_quad_expr
)I assume that gurobi had difficulties to understand the following:
quad_expr_c[c] == gp.quicksum(z_c_r[c, r] * mu_c_r[c, r] for r in R_c[c])
Best
Paul0
Please sign in to leave a comment.
Comments
2 comments