fix variables to convert NLP to LP
AnsweredI have a problem with the following form
where f and h are linear functions, and g(x,y) is a nonlinear function. If I fix x, g(x,y) will be a non-convex quadratic function. If I fix y, g(x,y) will be a linear function.
Gurobi cannot solve this problem directly. So I utilize an iterative framework to solve it.
Algorithm:
Step 1. Fix x solve y
Step 2. Fix y solve x
However, for each step, I have to recreate the model instead of fixing variables in the original model.
The following is a sample model, the number of vars is relatively large, and recreating the model may take some time:
from gurobipy import*
m = Model()
x = m.addVars(10**5)
y = m.addVars(10**5)
nlp_constrs_coeffs=range(10) #
c = m.addConstrs(quicksum(x[i] *y[i] *y[i] * k ** 2 for i in x) >=10 ** 6 for k in nlp_constrs_coeffs)
# c2 = m.addConstrs(x[i] == 2 for i in x) # iteratively fix x and y
# c3 = m.addConstrs(y[i] == 3 for i in y)
m.setObjective(x.sum() + y.sum())
m.optimize()
My questions:
Is there a way to avoid recreating the model every time to save the model building time or let gurobi know after fixing some variables the left model is a QP or LP?
-
It is not possible to directly construct nonlinear expressions in Gurobi such as the \(x\cdot y^2\). This is because the QuadExpr object allows for at most quadratic terms and the operation QuadExpr * GRBVar is not defined.
For your case, it would be best to have 2 models, a "fixed x model" and a "fixed y model". For the particular example you presented, this would be similar to
from gurobipy import*
mxfixed = Model("x_fixed")
mxfixed.setParam("NonConvex",2)
x_xfixed = [2]*10
y_xfixed = mxfixed.addVars(10)
c_xfixed = mxfixed.addConstr(quicksum(x_xfixed[i] *y_xfixed[i] *y_xfixed[i] for i in range(10)) >=10)
mxfixed.setObjective(sum(x_xfixed) + y_xfixed.sum())
mxfixed.optimize()
myfixed = Model("y_fixed")
x_myfixed = myfixed.addVars(10)
y_myfixed = [3]*10
c = myfixed.addConstr(quicksum(x_myfixed[i] *y_myfixed[i] *y_myfixed[i] for i in range(10)) >=10)
myfixed.setObjective(x_myfixed.sum() + sum(y_myfixed))
myfixed.optimize()Best regards,
Jaromił0 -
I use an iterative framework, which first fixes x, then y, then x again.
And I have a concern that in my previous post: https://support.gurobi.com/hc/en-us/community/posts/4974386567697/comments/6031986401041 you told me that constructing new expressions can be way faster than removing variables from expression.
But in this situation, is changing the expression coefficient faster than constructing new expressions?
0 -
If I understand your idea correctly, you will have to use the chgCoeff method to change particular coefficient depicting your fixed x and y values in the corresponding "fixed x" or "fixed y" model. In most cases, it should be the fastest. Still, I think it is best if you test both, the chgCoeff method vs constructing a new constraint and removing the old one.
0
Please sign in to leave a comment.
Comments
3 comments