Error when building nonlinear constraints using addGenConstrXxx() and addConstr()
AnsweredI am using addGenConstrXxx() and addConstr() to model some nonlinear constraints.
It seems like the consecutive usage of those functions is not always supported. (I am using Gurobi 10.0.0.)
The example code below leads to an error when optimizing the model (.updated runs through) when the linear constraint
GRBConstr sum = MILP.addConstr(var6 == var5 + var4, "sum"); // var6 = var5 + var4 = var5 + var3 * sin(var1)
is included. It looks like Gurobi can not handle the product behind var4, since replacing it with var2 = sin(var1) runs through.
Is there any other way to model to include a product in a linear constraint?
// Create a Gurobi environment
GRBEnv environment = GRBEnv::GRBEnv(true); // Gurobi environment containing the optization problem
environment.set(GRB_IntParam_LogToConsole, 0);
environment.start();
GRBModel MILP = GRBModel(environment); // Create an empty model
// Create Gurobi variables
GRBVar var1 = MILP.addVar(-1.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var1");
GRBVar var2 = MILP.addVar(0.5, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var2");
GRBVar var3 = MILP.addVar(1.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var3");
GRBVar var4 = MILP.addVar(-4.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var4");
GRBVar var5 = MILP.addVar(-3.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var5");
GRBVar var6 = MILP.addVar(10.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var6");
GRBVar var7 = MILP.addVar(0.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var7");
GRBVar var8 = MILP.addVar(0.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "var8");
// Create constraints
GRBGenConstr sinus = MILP.addGenConstrSin(var1,var2,"sin"); // var2 = sin(var1)
GRBQConstr mixed_product = MILP.addQConstr(var4 == var3 * var2, "mixed_product"); // var4 = var3 * var2 = var3 * sin(var1)
GRBConstr sum = MILP.addConstr(var6 == var5 + var4, "sum"); // var6 = var5 + var4 = var5 + var3 * sin(var1)
GRBGenConstr power = MILP.addGenConstrPow(var6, var7, 2, "power"); // var7 = var6 * var 6 = (var5 + var3 * sin(var1)) * (var5 + var3 * sin(var1))
std::cout << "Test 0" << std::endl;
MILP.update();
std::cout << "Test 1" << std::endl;
MILP.optimize();
std::cout << "Optimization status = " << MILP.get(GRB_IntAttr_Status) << std::endl;
-
Hi Christian,
When I run your code the error that is produced is the following:
Error code = 10021
Quadratic equality constraints are non-convex. Set NonConvex parameter to 2 to solve model.If you follow the suggestion in the error message, and set the NonConvex parameter to 2:
environment.set(GRB_IntParam_NonConvex, 2);
then your model solves quickly.
To explain the use of this parameter I am pasting an excerpt from our reference manual:
Solving models with non-convex quadratic constraints is typically much more expensive. To avoid accidentally solving a much harder problem than may have been intended, Gurobi rejects such constraints by default. If you set the NonConvex parameter to 2, however, then Gurobi will accept arbitrary quadratic constraints and attempt to solve the resulting model.
- Riley
0 -
Thanks, setting the parameter solves it.
In Visual Studio it was just dying without showing the error code.
0 -
Ah, yes I forgot to mention I was error handling:
try {
...
} catch(GRBException e) {
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
}- Riley
0
Please sign in to leave a comment.
Comments
3 comments