Nlconstr Examples#
This section includes source code for all of the Gurobi nlconstr
examples. The same source code can be found in the examples
directory of the Gurobi distribution.
/* Copyright 2026, Gurobi Optimization, LLC */
/* This example formulates and solves the following simple nonlinear model
using the nonlinear constraint API:
minimize x - y
subject to sin(x) * x + x^2 * y <= 1
y = cos(x) (<=> cos(x) - y = 0)
-1 <= x <= 2
0 <= y <= 2
The nonlinear constraint is set via GRBaddnlconstr() using an expression tree.
Then we retrieve the tree with GRBgetnlconstr() and verify it, delete it with
GRBdelnlconstrs(), replace it with a simple linear constraint, and re-optimize.
*/
#include <stdlib.h>
#include <stdio.h>
#include "gurobi_c.h"
int
main(int argc,
char *argv[])
{
GRBenv *env = NULL;
GRBmodel *model = NULL;
int error = 0;
/* Variable data: x (index 0), y (index 1) */
double lb[2] = {-1.0, 0.0};
double ub[2] = { 2.0, 2.0};
char *varnames[2] = {"x", "y"};
double obj[2] = {1.0, -1.0};
/* Expression tree for sin(x) * x + x^2 * y (10 nodes)
*
* node 0: PLUS (root)
* node 1: MULTIPLY (child of 0) -> sin(x) * x
* node 2: SIN (child of 1)
* node 3: VARIABLE x (child of 2)
* node 4: VARIABLE x (child of 1)
* node 5: MULTIPLY (child of 0) -> x^2 * y
* node 6: POW (child of 5)
* node 7: VARIABLE x (child of 6)
* node 8: CONSTANT 2 (child of 6)
* node 9: VARIABLE y (child of 5)
*/
int nnodes1 = 10;
int opcode1[10] = {GRB_OPCODE_PLUS, /* 0: root */
GRB_OPCODE_MULTIPLY, /* 1: sin(x)*x */
GRB_OPCODE_SIN, /* 2: sin(...) */
GRB_OPCODE_VARIABLE, /* 3: x */
GRB_OPCODE_VARIABLE, /* 4: x */
GRB_OPCODE_MULTIPLY, /* 5: x^2 * y */
GRB_OPCODE_POW, /* 6: x^2 */
GRB_OPCODE_VARIABLE, /* 7: x */
GRB_OPCODE_CONSTANT, /* 8: 2.0 */
GRB_OPCODE_VARIABLE}; /* 9: y */
double data1[10] = {-1.0, -1.0, -1.0,
0.0, /* x index */
0.0, /* x index */
-1.0, -1.0,
0.0, /* x index */
2.0,
1.0}; /* y index */
int parent1[10] = {-1, 0, 1, 2, 1, 0, 5, 6, 6, 5};
/* Expression tree for cos(x) - y = 0 (4 nodes)
*
* node 0: MINUS (root)
* node 1: COS (child of 0)
* node 2: VARIABLE x (child of 1)
* node 3: VARIABLE y (child of 0)
*/
int nnodes2 = 4;
int opcode2[4] = {GRB_OPCODE_MINUS, /* 0: root */
GRB_OPCODE_COS, /* 1: cos(...) */
GRB_OPCODE_VARIABLE, /* 2: x */
GRB_OPCODE_VARIABLE}; /* 3: y */
double data2[4] = {-1.0, -1.0,
0.0, /* x index */
1.0}; /* y index */
int parent2[4] = {-1, 0, 1, 0};
/* Data for querying solution and NL constraint */
double sol[2];
int optimstatus;
double objval;
int nnodes_out;
/* Create environment */
error = GRBloadenv(&env, "nlconstr.log");
if (error) goto QUIT;
/* Create model with two variables */
error = GRBnewmodel(env, &model, "nlconstr", 2, obj, lb, ub, NULL,
varnames);
if (error) goto QUIT;
/* Add constraint: sin(x) * x + x^2 * y <= 1 */
error = GRBaddnlconstr(model, nnodes1, opcode1, data1, parent1,
GRB_LESS_EQUAL, 1.0, "NonlinearConstraint1");
if (error) goto QUIT;
/* Add constraint: cos(x) - y = 0 */
error = GRBaddnlconstr(model, nnodes2, opcode2, data2, parent2,
GRB_EQUAL, 0.0, "NonlinearConstraint2");
if (error) goto QUIT;
/* Optimize model */
error = GRBoptimize(model);
if (error) goto QUIT;
/* Capture solution information */
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimstatus);
if (error) goto QUIT;
printf("\nFirst solve (nonlinear constraints)\n");
if (optimstatus == GRB_OPTIMAL) {
error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &objval);
if (error) goto QUIT;
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, 2, sol);
if (error) goto QUIT;
printf("Optimal objective: %.4e\n", objval);
printf(" x=%.6f, y=%.6f\n", sol[0], sol[1]);
} else if (optimstatus == GRB_INF_OR_UNBD) {
printf("Model is infeasible or unbounded\n");
} else {
printf("Optimization was stopped early\n");
}
/* Retrieve number of nodes of first nonlinear constraint and print it */
error = GRBgetnlconstr(model, 0, &nnodes_out, NULL, NULL, NULL);
if (error) goto QUIT;
printf("\nRetrieved NL constraint with %d nodes\n", nnodes_out);
/* Delete both nonlinear constraints */
{
int ind[2] = {0, 1};
error = GRBdelnlconstrs(model, 2, ind);
if (error) goto QUIT;
printf("Deleted nonlinear constraints\n");
}
/* Add a simple linear constraint instead: x + y >= 1 */
{
int ind[2] = {0, 1};
double val[2] = {1.0, 1.0};
error = GRBaddconstr(model, 2, ind, val, GRB_GREATER_EQUAL, 1.0, "LinearConstraint");
if (error) goto QUIT;
}
/* Re-optimize */
error = GRBoptimize(model);
if (error) goto QUIT;
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimstatus);
if (error) goto QUIT;
printf("\nSecond solve (linear constraint)\n");
if (optimstatus == GRB_OPTIMAL) {
error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &objval);
if (error) goto QUIT;
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, 2, sol);
if (error) goto QUIT;
printf("Optimal objective: %.4e\n", objval);
printf(" x=%.6f, y=%.6f\n", sol[0], sol[1]);
} else if (optimstatus == GRB_INF_OR_UNBD) {
printf("Model is infeasible or unbounded\n");
} else {
printf("Optimization was stopped early\n");
}
QUIT:
/* Error reporting */
if (error) {
printf("ERROR: %s\n", GRBgeterrormsg(env));
exit(1);
}
/* Free model */
GRBfreemodel(model);
/* Free environment */
GRBfreeenv(env);
return 0;
}
/* Copyright 2026, Gurobi Optimization, LLC */
/* This example formulates and solves the following simple nonlinear model
using the nonlinear constraint API:
minimize x - y
subject to sin(x) * x + x^2 * y <= 1
y = cos(x) (<=> cos(x) - y = 0)
-1 <= x <= 2
0 <= y <= 2
The nonlinear constraint is set via addNLConstr() using an expression tree.
Then we retrieve the tree with getNLConstrLHS() and verify it, delete it
with remove(), replace it with a simple linear constraint, and re-optimize.
*/
#include "gurobi_c++.h"
#include <cmath>
using namespace std;
int
main(int argc,
char *argv[])
{
try {
/* Create environment and model */
GRBEnv env = GRBEnv("nlconstr.log");
GRBModel model = GRBModel(env);
/* Create variables: x in [-1, 2], y in [0, 2] */
GRBVar x = model.addVar(-1.0, 2.0, 1.0, GRB_CONTINUOUS, "x");
GRBVar y = model.addVar(0.0, 2.0, -1.0, GRB_CONTINUOUS, "y");
/* Expression tree for sin(x) * x + x^2 * y (10 nodes)
*
* node 0: PLUS (root)
* node 1: MULTIPLY (child of 0) -> sin(x) * x
* node 2: SIN (child of 1)
* node 3: VARIABLE x (child of 2)
* node 4: VARIABLE x (child of 1)
* node 5: MULTIPLY (child of 0) -> x^2 * y
* node 6: POW (child of 5)
* node 7: VARIABLE x (child of 6)
* node 8: CONSTANT 2 (child of 6)
* node 9: VARIABLE y (child of 5)
*/
int nnodes_in1 = 10;
int opcode1[10] = {GRB_OPCODE_PLUS,
GRB_OPCODE_MULTIPLY,
GRB_OPCODE_SIN,
GRB_OPCODE_VARIABLE,
GRB_OPCODE_VARIABLE,
GRB_OPCODE_MULTIPLY,
GRB_OPCODE_POW,
GRB_OPCODE_VARIABLE,
GRB_OPCODE_CONSTANT,
GRB_OPCODE_VARIABLE};
double data1[10] = {-1.0, -1.0, -1.0,
(double) x.index(),
(double) x.index(),
-1.0, -1.0,
(double) x.index(),
2.0,
(double) y.index()};
int parent1[10] = {-1, 0, 1, 2, 1, 0, 5, 6, 6, 5};
/* Expression tree for cos(x) - y = 0 (4 nodes)
*
* node 0: MINUS (root)
* node 1: COS (child of 0)
* node 2: VARIABLE x (child of 1)
* node 3: VARIABLE y (child of 0)
*/
int nnodes_in2 = 4;
int opcode2[4] = {GRB_OPCODE_MINUS, /* 0: root */
GRB_OPCODE_COS, /* 1: cos(...) */
GRB_OPCODE_VARIABLE, /* 2: x */
GRB_OPCODE_VARIABLE}; /* 3: y */
double data2[4] = {-1.0, -1.0,
(double) x.index(),
(double) y.index()};
int parent2[4] = {-1, 0, 1, 0};
/* Add nonlinear constraint: sin(x)*x + x^2*y <= 1 */
GRBNLConstr nlc1 = model.addNLConstr(nnodes_in1, opcode1, data1, parent1,
GRB_LESS_EQUAL, 1.0,
"NonlinearConstraint1");
/* Add nonlinear constraint: cos(x) - y = 0 */
GRBNLConstr nlc2 = model.addNLConstr(nnodes_in2, opcode2, data2, parent2,
GRB_EQUAL, 0.0,
"NonlinearConstraint2");
/* Optimize model */
model.optimize();
int status = model.get(GRB_IntAttr_Status);
cout << "\nFirst solve (nonlinear constraints)" << endl;
if (status == GRB_OPTIMAL) {
cout << "Optimal objective: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
cout << " x = " << x.get(GRB_DoubleAttr_X)
<< ", y = " << y.get(GRB_DoubleAttr_X) << endl;
} else if (status == GRB_INF_OR_UNBD) {
cout << "Model is infeasible or unbounded" << endl;
} else {
cout << "Optimization was stopped early" << endl;
}
/* Retrieve number of nodes (first pass with NULLs) */
int nnodes_out = -1;
model.getNLConstrLHS(nlc1, &nnodes_out, NULL, NULL, NULL);
cout << "\nRetrieved NL constraint with " << nnodes_out << " nodes" << endl;
/* Retrieve full tree (second pass) */
int* opcode_out = new int[nnodes_out];
double* data_out = new double[nnodes_out];
int* parent_out = new int[nnodes_out];
model.getNLConstrLHS(nlc1, &nnodes_out, opcode_out, data_out, parent_out);
/* Verify tree matches what we added */
for (int i = 0; i < nnodes_out; i++) {
if (opcode_out[i] != opcode1[i] || parent_out[i] != parent1[i] || data_out[i] != data1[i]) {
cout << "ERROR: tree mismatch at node " << i << endl;
}
}
delete[] opcode_out;
delete[] data_out;
delete[] parent_out;
/* Delete nonlinear constraints */
model.remove(nlc1);
model.remove(nlc2);
model.update();
cout << "Deleted nonlinear constraints" << endl;
/* Add a simple linear constraint instead: x + y >= 1 */
model.addConstr(x + y >= 1.0, "LinearConstraint");
/* Re-optimize */
model.optimize();
status = model.get(GRB_IntAttr_Status);
cout << "\nSecond solve (linear constraint)" << endl;
if (status == GRB_OPTIMAL) {
cout << "Optimal objective: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
cout << " x = " << x.get(GRB_DoubleAttr_X)
<< ", y = " << y.get(GRB_DoubleAttr_X) << endl;
} else if (status == GRB_INF_OR_UNBD) {
cout << "Model is infeasible or unbounded" << endl;
} else {
cout << "Optimization was stopped early" << endl;
}
} catch(GRBException e) {
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
} catch(...) {
cout << "Exception during optimization" << endl;
}
return 0;
}
// Copyright 2026, Gurobi Optimization, LLC
// This example formulates and solves the following simple nonlinear model
// using the nonlinear API:
//
// minimize x - y
// subject to sin(x) * x + x^2 * y <= 1
// y = cos(x) (<=> cos(x) - y = 0)
// -1 <= x <= 2
// 0 <= y <= 2
//
// The example is split into two functions that show two ways to build the
// nonlinear constraints with the new NL API:
//
// - nlconstrNLAPI(): uses the nonlinear expression API. The left-hand sides
// of the constraints are built as GRBNLExpr objects with the overloaded
// operators, the nonlinear functions hosted on GRBNLExpr, and the Pow()
// helper, and passed directly to AddNLConstr().
//
// - nlconstrNLAPIAdv(): uses the advanced expression-tree variant of
// AddNLConstr(), where the left-hand side of each constraint is described
// with arrays of opcodes, data, and parent pointers.
//
// In both cases we retrieve a nonlinear constraint with GetNLConstrLHS(),
// delete it with Remove(), replace it with a simple linear constraint, and
// re-optimize.
using System;
using Gurobi;
using static Gurobi.GRBNLExpr;
class nlconstr_cs
{
/// <summary>
/// Run both ways of building nonlinear constraints: the nonlinear
/// expression API and the advanced expression-tree API.
/// </summary>
static void Main()
{
try {
// First, the nonlinear expression API
nlconstrNLAPI();
// Then, the advanced expression-tree API
nlconstrNLAPIAdv();
} catch (GRBException e) {
Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
}
}
/// <summary>
/// Formulate the model with the nonlinear expression API, passing
/// GRBNLExpr left-hand sides to AddNLConstr().
/// </summary>
static void nlconstrNLAPI()
{
// Create environment
GRBEnv env = new GRBEnv("nlconstr.log");
// Create empty model
GRBModel model = new GRBModel(env);
// Create variables
GRBVar x = model.AddVar(-1.0, 2.0, 1.0, GRB.CONTINUOUS, "x");
GRBVar y = model.AddVar( 0.0, 2.0, -1.0, GRB.CONTINUOUS, "y");
// Add nonlinear constraint: sin(x)*x + x^2*y <= 1.
// The left-hand side is built as a GRBNLExpr:
// GRBNLExpr.Sin(x) -> sin(x)
// GRBNLExpr.Pow(x, 2.0) -> x^2 (a SQUARE node)
GRBNLConstr nlc1 = model.AddNLConstr(
Sin(x) * x + Pow(x, 2.0) * y <= 1.0,
"NonlinearConstraint1");
// Add nonlinear constraint: cos(x) - y = 0
GRBNLConstr nlc2 = model.AddNLConstr(Cos(x) - y == 0.0,
"NonlinearConstraint2");
// Optimize model
model.Optimize();
Console.WriteLine("\nFirst solve (nonlinear constraints)");
if (model.Status == GRB.Status.OPTIMAL) {
Console.WriteLine("Optimal objective: {0:E4}", model.ObjVal);
Console.WriteLine(" x={0:F6}, y={1:F6}", x.X, y.X);
} else if (model.Status == GRB.Status.INF_OR_UNBD) {
Console.WriteLine("Model is infeasible or unbounded");
} else {
Console.WriteLine("Optimization was stopped early");
}
// Retrieve the first nonlinear constraint as a GRBNLExpr and print it
GRBNLExpr lhs = model.GetNLConstrLHS(nlc1);
Console.WriteLine("\nRetrieved NL constraint: \"" + lhs + "\"");
// Delete the nonlinear constraints
model.Remove(nlc1);
model.Remove(nlc2);
model.Update();
Console.WriteLine("Deleted nonlinear constraints");
// Add a simple linear constraint instead: x + y >= 1
model.AddConstr(x + y, GRB.GREATER_EQUAL, 1.0, "LinearConstraint");
// Re-optimize
model.Optimize();
Console.WriteLine("\nSecond solve (linear constraint)");
if (model.Status == GRB.Status.OPTIMAL) {
Console.WriteLine("Optimal objective: {0:E4}", model.ObjVal);
Console.WriteLine(" x={0:F6}, y={1:F6}", x.X, y.X);
} else if (model.Status == GRB.Status.INF_OR_UNBD) {
Console.WriteLine("Model is infeasible or unbounded");
} else {
Console.WriteLine("Optimization was stopped early");
}
// Dispose of model and env
model.Dispose();
env.Dispose();
}
/// <summary>
/// Formulate the model with the advanced expression-tree variant of
/// AddNLConstr(), where the left-hand side of each constraint is
/// described with arrays of opcodes, data, and parent pointers.
/// </summary>
static void nlconstrNLAPIAdv()
{
// Create environment
GRBEnv env = new GRBEnv("nlconstr.log");
// Create empty model
GRBModel model = new GRBModel(env);
// Create variables
GRBVar x = model.AddVar(-1.0, 2.0, 1.0, GRB.CONTINUOUS, "x");
GRBVar y = model.AddVar( 0.0, 2.0, -1.0, GRB.CONTINUOUS, "y");
// Expression tree for sin(x) * x + x^2 * y (10 nodes)
//
// node 0: PLUS (root)
// node 1: MULTIPLY (child of 0) -> sin(x) * x
// node 2: SIN (child of 1)
// node 3: VARIABLE x (child of 2)
// node 4: VARIABLE x (child of 1)
// node 5: MULTIPLY (child of 0) -> x^2 * y
// node 6: POW (child of 5)
// node 7: VARIABLE x (child of 6)
// node 8: CONSTANT 2 (child of 6)
// node 9: VARIABLE y (child of 5)
int[] opcode1 = new int[] {
GRB.OPCODE_PLUS,
GRB.OPCODE_MULTIPLY,
GRB.OPCODE_SIN,
GRB.OPCODE_VARIABLE,
GRB.OPCODE_VARIABLE,
GRB.OPCODE_MULTIPLY,
GRB.OPCODE_POW,
GRB.OPCODE_VARIABLE,
GRB.OPCODE_CONSTANT,
GRB.OPCODE_VARIABLE
};
double[] data1 = new double[] {
-1.0, -1.0, -1.0,
x.Index,
x.Index,
-1.0, -1.0,
x.Index,
2.0,
y.Index
};
int[] parent1 = new int[] {-1, 0, 1, 2, 1, 0, 5, 6, 6, 5};
// Expression tree for cos(x) - y = 0 (4 nodes)
//
// node 0: MINUS (root)
// node 1: COS (child of 0)
// node 2: VARIABLE x (child of 1)
// node 3: VARIABLE y (child of 0)
int[] opcode2 = new int[] {
GRB.OPCODE_MINUS,
GRB.OPCODE_COS,
GRB.OPCODE_VARIABLE,
GRB.OPCODE_VARIABLE
};
double[] data2 = new double[] {
-1.0, -1.0,
x.Index,
y.Index
};
int[] parent2 = new int[] {-1, 0, 1, 0};
// Add nonlinear constraint: sin(x)*x + x^2*y <= 1
GRBNLConstr nlc1 = model.AddNLConstr(opcode1, data1, parent1,
GRB.LESS_EQUAL, 1.0,
"NonlinearConstraint1");
// Add nonlinear constraint: cos(x) - y = 0
GRBNLConstr nlc2 = model.AddNLConstr(opcode2, data2, parent2,
GRB.EQUAL, 0.0,
"NonlinearConstraint2");
// Optimize model
model.Optimize();
Console.WriteLine("\nFirst solve (nonlinear constraints)");
if (model.Status == GRB.Status.OPTIMAL) {
Console.WriteLine("Optimal objective: {0:E4}", model.ObjVal);
Console.WriteLine(" x={0:F6}, y={1:F6}", x.X, y.X);
} else if (model.Status == GRB.Status.INF_OR_UNBD) {
Console.WriteLine("Model is infeasible or unbounded");
} else {
Console.WriteLine("Optimization was stopped early");
}
// Retrieve the first nonlinear constraint and print the number of nodes
int nnodes;
model.GetNLConstrLHS(nlc1, out nnodes, null, null, null);
Console.WriteLine("\nRetrieved NL constraint with " + nnodes + " nodes");
// Delete the nonlinear constraints
model.Remove(nlc1);
model.Remove(nlc2);
model.Update();
Console.WriteLine("Deleted nonlinear constraints");
// Add a simple linear constraint instead: x + y >= 1
model.AddConstr(x + y, GRB.GREATER_EQUAL, 1.0, "LinearConstraint");
// Re-optimize
model.Optimize();
Console.WriteLine("\nSecond solve (linear constraint)");
if (model.Status == GRB.Status.OPTIMAL) {
Console.WriteLine("Optimal objective: {0:E4}", model.ObjVal);
Console.WriteLine(" x={0:F6}, y={1:F6}", x.X, y.X);
} else if (model.Status == GRB.Status.INF_OR_UNBD) {
Console.WriteLine("Model is infeasible or unbounded");
} else {
Console.WriteLine("Optimization was stopped early");
}
// Dispose of model and env
model.Dispose();
env.Dispose();
}
}
/* Copyright 2026, Gurobi Optimization, LLC */
/* This example formulates and solves the following simple nonlinear model
using the nonlinear constraint API:
minimize x - y
subject to sin(x) * x + x^2 * y <= 1
y = cos(x) (<=> cos(x) - y = 0)
-1 <= x <= 2
0 <= y <= 2
The nonlinear constraint is set via addNLConstr() using an expression tree.
Then we retrieve the tree with getNLConstrLHS() and verify it, delete it with
remove(), replace it with a simple linear constraint, and re-optimize.
*/
import com.gurobi.gurobi.*;
public class NLConstr {
public static void main(String[] args) {
try {
// Create environment
GRBEnv env = new GRBEnv("nlconstr.log");
// Create empty model
GRBModel model = new GRBModel(env);
// Create variables
GRBVar x = model.addVar(-1.0, 2.0, 1.0, GRB.CONTINUOUS, "x");
GRBVar y = model.addVar( 0.0, 2.0, -1.0, GRB.CONTINUOUS, "y");
/* Expression tree for sin(x) * x + x^2 * y (10 nodes)
*
* node 0: PLUS (root)
* node 1: MULTIPLY (child of 0) -> sin(x) * x
* node 2: SIN (child of 1)
* node 3: VARIABLE x (child of 2)
* node 4: VARIABLE x (child of 1)
* node 5: MULTIPLY (child of 0) -> x^2 * y
* node 6: POW (child of 5)
* node 7: VARIABLE x (child of 6)
* node 8: CONSTANT 2 (child of 6)
* node 9: VARIABLE y (child of 5)
*/
int[] opcode1 = new int[] {
GRB.OPCODE_PLUS, // 0: root
GRB.OPCODE_MULTIPLY, // 1: sin(x)*x
GRB.OPCODE_SIN, // 2: sin(...)
GRB.OPCODE_VARIABLE, // 3: x
GRB.OPCODE_VARIABLE, // 4: x
GRB.OPCODE_MULTIPLY, // 5: x^2 * y
GRB.OPCODE_POW, // 6: x^2
GRB.OPCODE_VARIABLE, // 7: x
GRB.OPCODE_CONSTANT, // 8: 2.0
GRB.OPCODE_VARIABLE // 9: y
};
double[] data1 = new double[] {
-1.0, -1.0, -1.0,
x.index(), // x index
x.index(), // x index
-1.0, -1.0,
x.index(), // x index
2.0,
y.index() // y index
};
int[] parent1 = new int[] {-1, 0, 1, 2, 1, 0, 5, 6, 6, 5};
/* Expression tree for cos(x) - y = 0 (4 nodes)
*
* node 0: MINUS (root)
* node 1: COS (child of 0)
* node 2: VARIABLE x (child of 1)
* node 3: VARIABLE y (child of 0)
*/
int[] opcode2 = new int[] {
GRB.OPCODE_MINUS, // 0: root
GRB.OPCODE_COS, // 1: cos(...)
GRB.OPCODE_VARIABLE, // 2: x
GRB.OPCODE_VARIABLE, // 3: y
};
double[] data2 = new double[] {
-1.0, -1.0,
x.index(), // x index
y.index() // y index
};
int[] parent2 = new int[] {-1, 0, 1, 0};
// Add nonlinear constraint: sin(x) * x + x^2 * y <= 1
GRBNLConstr nlc1 = model.addNLConstr(opcode1, data1, parent1,
GRB.LESS_EQUAL, 1.0,
"NonlinearConstraint1");
// Add nonlinear constraint: cos(x) - y = 0
GRBNLConstr nlc2 = model.addNLConstr(opcode2, data2, parent2,
GRB.EQUAL, 0.0,
"NonlinearConstraint2");
// Optimize model
model.optimize();
System.out.println("\nFirst solve (nonlinear constraints)");
if (model.get(GRB.IntAttr.Status) == GRB.OPTIMAL) {
System.out.printf("Optimal objective: %.4e%n",
model.get(GRB.DoubleAttr.ObjVal));
System.out.printf(" x=%.6f, y=%.6f%n",
x.get(GRB.DoubleAttr.X),
y.get(GRB.DoubleAttr.X));
} else if (model.get(GRB.IntAttr.Status) == GRB.INF_OR_UNBD) {
System.out.println("Model is infeasible or unbounded");
} else {
System.out.println("Optimization was stopped early");
}
// Retrieve the nonlinear constraint and print the number of nodes
int[] nnodes = new int[1];
model.getNLConstrLHS(nlc1, nnodes, null, null, null);
System.out.println("\nRetrieved NL constraint with " + nnodes[0] +
" nodes");
// Delete nonlinear constraints
model.remove(nlc1);
model.remove(nlc2);
model.update();
System.out.println("Deleted nonlinear constraints");
// Add a simple linear constraint instead: x + y >= 1
GRBLinExpr expr = new GRBLinExpr();
expr.addTerm(1.0, x);
expr.addTerm(1.0, y);
model.addConstr(expr, GRB.GREATER_EQUAL, 1.0, "LinearConstraint");
// Re-optimize
model.optimize();
System.out.println("\nSecond solve (linear constraint)");
if (model.get(GRB.IntAttr.Status) == GRB.OPTIMAL) {
System.out.printf("Optimal objective: %.4e%n",
model.get(GRB.DoubleAttr.ObjVal));
System.out.printf(" x=%.6f, y=%.6f%n",
x.get(GRB.DoubleAttr.X),
y.get(GRB.DoubleAttr.X));
} else if (model.get(GRB.IntAttr.Status) == GRB.INF_OR_UNBD) {
System.out.println("Model is infeasible or unbounded");
} else {
System.out.println("Optimization was stopped early");
}
// Dispose of model and environment
model.dispose();
env.dispose();
} catch (GRBException e) {
System.out.println("Error code: " + e.getErrorCode() + ". " +
e.getMessage());
}
}
}
function nlconstr()
% Copyright 2026, Gurobi Optimization, LLC
%
% This example formulates and solves the following simple nonlinear model
% using the nonlinear constraint API:
%
% minimize
% x - y
% subject to
% sin(x) * x + x^2 * y <= 1
% y = cos(x) (<=> cos(x) - y = 0)
% -1 <= x <= 2
% 0 <= y <= 2
%
% The nonlinear constraints are set through the model.nlcon field, a struct
% array holding the expression tree of each constraint together with its
% sense and right-hand side.
model.varnames = {'x', 'y'};
% Set linear objective: x - y
model.obj = [1, -1];
% Bounds: -1 <= x <= 2, 0 <= y <= 2
model.lb = [-1; 0];
model.ub = [ 2; 2];
% There are no linear constraints, but the model still needs a constraint
% matrix with one column per variable
model.A = sparse(0, 2);
% Add nonlinear constraint: sin(x) * x + x^2 * y <= 1
%
% The left-hand side is given as an expression tree with 10 nodes. Every node
% has an opcode, a data value, and the index of its parent node. Nodes are
% 1-based, and the root node is marked by a parent of 0. The data value of a
% VARIABLE node is the 1-based index of that variable, the data value of a
% CONSTANT node is the constant itself, and all other nodes use -1.
%
% node 1: PLUS (root)
% node 2: MULTIPLY (child of 1) -> sin(x) * x
% node 3: SIN (child of 2)
% node 4: VARIABLE x (child of 3)
% node 5: VARIABLE x (child of 2)
% node 6: MULTIPLY (child of 1) -> x^2 * y
% node 7: POW (child of 6)
% node 8: VARIABLE x (child of 7)
% node 9: CONSTANT 2 (child of 7)
% node 10: VARIABLE y (child of 6)
model.nlcon(1).opcode = [ ...
GRB.OPCODE_PLUS, ... % 1: root
GRB.OPCODE_MULTIPLY, ... % 2: sin(x) * x
GRB.OPCODE_SIN, ... % 3: sin(...)
GRB.OPCODE_VARIABLE, ... % 4: x
GRB.OPCODE_VARIABLE, ... % 5: x
GRB.OPCODE_MULTIPLY, ... % 6: x^2 * y
GRB.OPCODE_POW, ... % 7: x^2
GRB.OPCODE_VARIABLE, ... % 8: x
GRB.OPCODE_CONSTANT, ... % 9: 2
GRB.OPCODE_VARIABLE, ... % 10: y
];
model.nlcon(1).data = [-1, -1, -1, 1, 1, -1, -1, 1, 2, 2];
model.nlcon(1).parent = [ 0, 1, 2, 3, 2, 1, 6, 7, 7, 6];
model.nlcon(1).sense = '<';
model.nlcon(1).rhs = 1;
model.nlcon(1).name = 'NonlinearConstraint1';
% Add nonlinear constraint: cos(x) - y = 0
%
% Only a constant right-hand side is allowed, so y = cos(x) is stated by
% moving y to the left-hand side. The expression tree has 4 nodes:
%
% node 1: MINUS (root)
% node 2: COS (child of 1)
% node 3: VARIABLE x (child of 2)
% node 4: VARIABLE y (child of 1)
model.nlcon(2).opcode = [ ...
GRB.OPCODE_MINUS, ... % 1: root
GRB.OPCODE_COS, ... % 2: cos(...)
GRB.OPCODE_VARIABLE, ... % 3: x
GRB.OPCODE_VARIABLE, ... % 4: y
];
model.nlcon(2).data = [-1, -1, 1, 2];
model.nlcon(2).parent = [ 0, 1, 2, 1];
model.nlcon(2).sense = '=';
model.nlcon(2).rhs = 0;
model.nlcon(2).name = 'NonlinearConstraint2';
% Optimize
params.logfile = 'nlconstr.log';
result = gurobi(model, params);
if strcmp(result.status, 'OPTIMAL')
for j = 1:2
fprintf('%s %e\n', model.varnames{j}, result.x(j));
end
fprintf('Obj: %e\n', result.objval);
else
fprintf('Optimization did not produce an optimal solution\n');
end
end
#!/usr/bin/env python3
# Copyright 2026, Gurobi Optimization, LLC
# This example formulates and solves the following simple nonlinear model
# using the nonlinear API:
#
# minimize x - y
# subject to sin(x) * x + x^2 * y <= 1
# y = cos(x) (<=> cos(x) - y = 0)
# -1 <= x <= 2
# 0 <= y <= 2
#
# The example uses the nonlinear expression API. The left-hand sides
# of the constraints are built as NLExpr objects with the overloaded
# operators, the nonlinear functions hosted in gurobipy.nlfunc, and the
# ** operator, and passed directly to addConstr().
#
# We retrieve a nonlinear constraint with getNLConstrLHS() together with
# its sense and rhs attribute and print it.
import gurobipy as gp
from gurobipy import GRB
from gurobipy.nlfunc import sin, cos
# Create new model
model = gp.Model("nlconstr")
# Create variables
x = model.addVar(lb=-1.0, ub=2.0, obj=1.0, vtype=GRB.CONTINUOUS, name="x")
y = model.addVar(lb=0.0, ub=2.0, obj=-1.0, vtype=GRB.CONTINUOUS, name="y")
# Add nonlinear constraint: sin(x)*x + x^2*y <= 1.
nlc1 = model.addConstr(sin(x) * x + x**2 * y <= 1.0, "NonlinearConstraint1")
# Add nonlinear constraint: cos(x) - y = 0
nlc2 = model.addConstr(cos(x) - y == 0.0, "NonlinearConstraint2")
# Optimize model
model.optimize()
print("\nSolving model with nonlinear constraints")
if model.Status == GRB.OPTIMAL:
print(f"Optimal objective: {model.ObjVal}")
print(f" x={x.X}, y={y.X}")
elif model.Status == GRB.INF_OR_UNBD:
print("Model is infeasible or unbounded")
else:
print("Optimization was stopped early")
# Retrieve the first nonlinear constraint as an NLExpr and print it
lhs = model.getNLConstrLHS(nlc1)
print(f'\nRetrieved NL constraint: "{lhs} {nlc1.NLCSense}= {nlc1.NLCRHS}"')
' Copyright 2026, Gurobi Optimization, LLC
'
' This example formulates and solves the following simple nonlinear model
' using the nonlinear API:
'
' minimize x - y
' subject to sin(x) * x + x^2 * y <= 1
' y = cos(x) (<=> cos(x) - y = 0)
' -1 <= x <= 2
' 0 <= y <= 2
'
' The example is split into two functions that show two ways to build the
' nonlinear constraints with the new NL API:
'
' - nlconstrNLAPI(): uses the nonlinear expression API. The left-hand sides
' of the constraints are built as GRBNLExpr objects with the overloaded
' operators, the nonlinear functions hosted on GRBNLExpr, and the Pow()
' helper, and passed directly to AddNLConstr().
'
' - nlconstrNLAPIAdv(): uses the advanced expression-tree variant of
' AddNLConstr(), where the left-hand side of each constraint is described
' with arrays of opcodes, data, and parent pointers.
'
' In both cases we retrieve a nonlinear constraint with GetNLConstrLHS(),
' delete it with Remove(), replace it with a simple linear constraint, and
' re-optimize.
Imports System
Imports Gurobi
Class nlconstr_vb
' Run both ways of building nonlinear constraints: the nonlinear
' expression API and the advanced expression-tree API.
Shared Sub Main()
Try
' First, the nonlinear expression API
nlconstrNLAPI()
' Then, the advanced expression-tree API
nlconstrNLAPIAdv()
Catch e As GRBException
Console.WriteLine("Error code: " & e.ErrorCode & ". " & e.Message)
End Try
End Sub
' nlconstrNLAPI(): formulates the model with the nonlinear expression API,
' passing GRBNLExpr left-hand sides to AddNLConstr().
Shared Sub nlconstrNLAPI()
' Create environment
Dim env As GRBEnv = New GRBEnv("nlconstr.log")
' Create empty model
Dim model As GRBModel = New GRBModel(env)
' Create variables
Dim x As GRBVar = model.AddVar(-1.0, 2.0, 1.0, GRB.CONTINUOUS, "x")
Dim y As GRBVar = model.AddVar(0.0, 2.0, -1.0, GRB.CONTINUOUS, "y")
' Add nonlinear constraint: sin(x)*x + x^2*y <= 1.
' The left-hand side is built as a GRBNLExpr:
' GRBNLExpr.Sin(x) -> sin(x)
' GRBNLExpr.Pow(x, 2.0) -> x^2 (a SQUARE node)
Dim nlc1 As GRBNLConstr = model.AddNLConstr( _
GRBNLExpr.Sin(x) * x + GRBNLExpr.Pow(x, 2.0) * y <= 1.0, _
"NonlinearConstraint1")
' Add nonlinear constraint: cos(x) - y = 0
Dim nlc2 As GRBNLConstr = model.AddNLConstr(GRBNLExpr.Cos(x) - y = 0.0, _
"NonlinearConstraint2")
' Optimize model
model.Optimize()
Console.WriteLine("")
Console.WriteLine("First solve (nonlinear constraints)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Retrieve the first nonlinear constraint as a GRBNLExpr and print it
Dim lhs As GRBNLExpr = model.GetNLConstrLHS(nlc1)
Console.WriteLine("")
Console.WriteLine("Retrieved NL constraint: """ & lhs.ToString() & """")
' Delete the nonlinear constraints
model.Remove(nlc1)
model.Remove(nlc2)
model.Update()
Console.WriteLine("Deleted nonlinear constraints")
' Add a simple linear constraint instead: x + y >= 1
model.AddConstr(x + y, GRB.GREATER_EQUAL, 1.0, "LinearConstraint")
' Re-optimize
model.Optimize()
Console.WriteLine("")
Console.WriteLine("Second solve (linear constraint)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Dispose of model and env
model.Dispose()
env.Dispose()
End Sub
' nlconstrNLAPIAdv(): formulates the model with the advanced
' expression-tree variant of AddNLConstr(), where the left-hand side of
' each constraint is described with arrays of opcodes, data, and parents.
Shared Sub nlconstrNLAPIAdv()
' Create environment
Dim env As GRBEnv = New GRBEnv("nlconstr.log")
' Create empty model
Dim model As GRBModel = New GRBModel(env)
' Create variables
Dim x As GRBVar = model.AddVar(-1.0, 2.0, 1.0, GRB.CONTINUOUS, "x")
Dim y As GRBVar = model.AddVar(0.0, 2.0, -1.0, GRB.CONTINUOUS, "y")
' Expression tree for sin(x) * x + x^2 * y (10 nodes)
'
' node 0: PLUS (root)
' node 1: MULTIPLY (child of 0) -> sin(x) * x
' node 2: SIN (child of 1)
' node 3: VARIABLE x (child of 2)
' node 4: VARIABLE x (child of 1)
' node 5: MULTIPLY (child of 0) -> x^2 * y
' node 6: POW (child of 5)
' node 7: VARIABLE x (child of 6)
' node 8: CONSTANT 2 (child of 6)
' node 9: VARIABLE y (child of 5)
Dim opcode1 As Integer() = New Integer() { _
GRB.OPCODE_PLUS, _
GRB.OPCODE_MULTIPLY, _
GRB.OPCODE_SIN, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_MULTIPLY, _
GRB.OPCODE_POW, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_CONSTANT, _
GRB.OPCODE_VARIABLE _
}
Dim data1 As Double() = New Double() { _
-1.0, -1.0, -1.0, _
x.Index, _
x.Index, _
-1.0, -1.0, _
x.Index, _
2.0, _
y.Index _
}
Dim parent1 As Integer() = New Integer() {-1, 0, 1, 2, 1, 0, 5, 6, 6, 5}
' Expression tree for cos(x) - y = 0 (4 nodes)
'
' node 0: MINUS (root)
' node 1: COS (child of 0)
' node 2: VARIABLE x (child of 1)
' node 3: VARIABLE y (child of 0)
Dim opcode2 As Integer() = New Integer() { _
GRB.OPCODE_MINUS, _
GRB.OPCODE_COS, _
GRB.OPCODE_VARIABLE, _
GRB.OPCODE_VARIABLE _
}
Dim data2 As Double() = New Double() { _
-1.0, -1.0, _
x.Index, _
y.Index _
}
Dim parent2 As Integer() = New Integer() {-1, 0, 1, 0}
' Add nonlinear constraint: sin(x)*x + x^2*y <= 1
Dim nlc1 As GRBNLConstr = model.AddNLConstr(opcode1, data1, parent1, _
GRB.LESS_EQUAL, 1.0, _
"NonlinearConstraint1")
' Add nonlinear constraint: cos(x) - y = 0
Dim nlc2 As GRBNLConstr = model.AddNLConstr(opcode2, data2, parent2, _
GRB.EQUAL, 0.0, _
"NonlinearConstraint2")
' Optimize model
model.Optimize()
Console.WriteLine("")
Console.WriteLine("First solve (nonlinear constraints)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Retrieve the first nonlinear constraint and print the number of nodes
Dim nnodes As Integer
model.GetNLConstrLHS(nlc1, nnodes, Nothing, Nothing, Nothing)
Console.WriteLine("")
Console.WriteLine("Retrieved NL constraint with " & nnodes & " nodes")
' Delete the nonlinear constraints
model.Remove(nlc1)
model.Remove(nlc2)
model.Update()
Console.WriteLine("Deleted nonlinear constraints")
' Add a simple linear constraint instead: x + y >= 1
model.AddConstr(x + y, GRB.GREATER_EQUAL, 1.0, "LinearConstraint")
' Re-optimize
model.Optimize()
Console.WriteLine("")
Console.WriteLine("Second solve (linear constraint)")
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine("Optimal objective: " & model.ObjVal.ToString("E4"))
Console.WriteLine(" x=" & x.X.ToString("F6") & _
", y=" & y.X.ToString("F6"))
ElseIf model.Status = GRB.Status.INF_OR_UNBD Then
Console.WriteLine("Model is infeasible or unbounded")
Else
Console.WriteLine("Optimization was stopped early")
End If
' Dispose of model and env
model.Dispose()
env.Dispose()
End Sub
End Class