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;
}