/* Copyright 2026, Gurobi Optimization, LLC */
/* This example formulates and solves the following simple nonlinear model
using the nonlinear objective API:
minimize sin(x) * x + x^2 * y
subject to x + y >= 1
-1 <= x <= 2
0 <= y <= 2
The nonlinear objective is set via GRBsetnlobj() using an expression tree.
Then we retrieve the tree with GRBgetnlobj() and verify it, delete it with
GRBdelnlobj(), replace it with a simple linear objective, 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"};
/* 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 = 10;
int opcode[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 data[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 parent[10] = {-1, 0, 1, 2, 1, 0, 5, 6, 6, 5};
/* Data for querying solution and NL objective */
double sol[2];
int optimstatus;
double objval;
int nnodes_out;
double linobj[2];
/* Create environment */
error = GRBloadenv(&env, "nlobj.log");
if (error) goto QUIT;
/* Create model with two variables, no linear objective */
error = GRBnewmodel(env, &model, "nlobj", 2, NULL, lb, ub, NULL,
varnames);
if (error) goto QUIT;
/* Add constraint: x + y >= 1 */
{
int cind[2] = {0, 1};
double cval[2] = {1.0, 1.0};
error = GRBaddconstr(model, 2, cind, cval, GRB_GREATER_EQUAL, 1.0, "c0");
if (error) goto QUIT;
}
/* Set nonlinear objective */
error = GRBsetnlobj(model, nnodes, opcode, data, parent);
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 objective)\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 the nonlinear objective and print the number of nodes */
error = GRBgetnlobj(model, &nnodes_out, NULL, NULL, NULL);
if (error) goto QUIT;
printf("\nRetrieved NL objective with %d nodes\n", nnodes_out);
/* Delete the nonlinear objective */
error = GRBdelnlobj(model);
if (error) goto QUIT;
printf("Deleted nonlinear objective\n");
/* Set a simple linear objective instead: minimize x + y */
linobj[0] = 1.0;
linobj[1] = 1.0;
error = GRBsetdblattrarray(model, GRB_DBL_ATTR_OBJ, 0, 2, linobj);
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 objective)\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;
}