Invalid argument to QuadExpr multiplication
回答済みHi,
I am using Gurobi for Python (gurobipy):
import gurobipy as gb
from gurobipy import *
I'm trying to take the minimization of an objective function that contains both continuous and binary variables. The continuous variables are used in a series of quadratic expressions in the objective function. For example:
obj_fn = y1*(200 + 20*G1 + 0.06*G1**2) + y2*(350 + 2*G2 + 0.01*G2**2) == 0
There are other constraints involved.
The binary variables are supposed to model power plants being ON or OFF. There are more than just two plants, but I listed just two as an example
However, it gives me the following error:
GurobiError: Invalid argument to QuadExpr multiplication
This is the style in which I've defined my decision variables:
G1 = q3.addVar(vtype=GRB.CONTINUOUS, lb=30, ub=300, name="G1")
y1 = q3.addVar(vtype=GRB.BINARY, name="y1")
These are additional parameters I've set:
q3.setParam('OutputFlag', False)
q3.setParam('QCPDual', 1)
Any idea on what is going wrong?
-
Hi Andrew,
Gurobi does not directly support expressions with degree greater than 2. The expression \((200 + 20 G_1 + 0.06 G_1^2)\) is already a quadratic expression. Multiplying it by the decision variable \(y_1\) would lead to creating the term \(0.06 y_1 G_1^2\) with degree three.
To model this, we need to define an auxiliary decision variable \(z\) where \(z = G_1^2\). We can then have \(y_1(200 + 20G_1 + 0.06z)\).
Please have a look at the article How do I model multilinear terms in Gurobi? for a more detailed explanation.
The parameter setting you identified is irrelevant to the error message, though I am not sure exactly why you are setting QCPDual parameter to 1.
Best regards,
Maliheh
0 -
Hi Maliheh! Thank you for your response.
I followed your instructions (and looked at the article you linked) and added the following:
Z1 = q3.addVar(vtype=GRB.CONTINUOUS, name="Z1")
Z2 = q3.addVar(vtype=GRB.CONTINUOUS, name="Z2")(q3 is the name of my problem)
I then replaced the quadratic terms in my objective function with them and made the following constraints:
q3.addConstr(Z1 == G1**2)
q3.addConstr(Z2 == G2**2)As a result, an error occured in which I was prompted to add the following code to my Python script:
q3.params.NonConvex = 2
Does it make sense that I would have to set that parameter equal to "2" in light of what I did? The problem seems to be solving optimally.
To answer your question on the QCPDual, I set it to "1" because the duals represent shadow prices, or locational marginal prices (LMPs), of different nodes in my network. It's useful for me to see their value since marginal costs are used extensively in modelling power system networks.
Unfortunately, q3.getAttr(GRB.Attr.Pi) throws an error message when I try to retrieve the dual prices. I think it has something to do with the non-convexity parameter that I set.
0 -
Does it make sense that I would have to set that parameter equal to "2" in light of what I did?
Yes, it makes sense. The equality quadratic constraints make the problem non-convex. Since handling non-convex constraints is generally hard, Gurobi by default rejects such constraints unless the user explicitly asks for solving the non-convex problem by setting the parameter NonConvex to 2. Alternatively, you can consider adding the auxiliary constraint as \(z_1 \geq G_1^2\) instead of the equality constraint. This will make the problem convex.
Your model is a mixed-integer quadratically constrained problem (MIQCP). The dual information is only available for the convex continuous models and it can be queried using the constraint attributes Pi and QCPi for the linear and quadratic constraints, respectively. For the quadratic constraints, the parameter QCPDual should be set to 1 as well.
After changing the equality quadratic constraints into inequalities, you can follow the steps below to retrieve the dual information on the fixed continuous model:
# optimize the original MIQCP model
model.optimize()
# create the fixed model by calling the method Model.fixed()
fixed = model.fixed()
# set the parameter QCPDual on the fixed model
fixed.params.QCPDual = 1
fixed.optimize()
# retrieve the dual of the quadratic constraints
fixed.getAttr("QCPi", fixed.getQConstrs())Best regards,
Maliheh
0
サインインしてコメントを残してください。
コメント
3件のコメント