Hide navigation sidebar
Hide table of contents sidebar
Back to top
Toggle table of contents sidebar

# Bilinear Examples

This section includes source code for all of the Gurobi bilinear examples. The same source code can be found in the `examples` directory of the Gurobi distribution.

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* This example formulates and solves the following simple bilinear model:

         maximize    x
         subject to  x + y + z <= 10
                     x * y <= 2          (bilinear inequality)
                     x * z + y * z == 1  (bilinear equality)
                     x, y, z non-negative (x integral in second version)
    */

    #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;
      double    sol[3];
      int       ind[3];
      double    val[3];
      double    obj[] = {1, 0, 0};
      int       qrow[2];
      int       qcol[2];
      double    qval[2];
      int       optimstatus;
      double    objval;

      /* Create environment */

      error = GRBloadenv(&env, "bilinear.log");
      if (error) goto QUIT;

      /* Create an empty model */

      error = GRBnewmodel(env, &model, "bilinear", 0, NULL, NULL, NULL, NULL,
                          NULL);
      if (error) goto QUIT;

      /* Add variables */

      error = GRBaddvars(model, 3, 0, NULL, NULL, NULL, obj, NULL, NULL, NULL,
                         NULL);
      if (error) goto QUIT;

      /* Change sense to maximization */

      error = GRBsetintattr(model, GRB_INT_ATTR_MODELSENSE, GRB_MAXIMIZE);
      if (error) goto QUIT;

      /* Linear constraint: x + y + z <= 10 */

      ind[0] = 0; ind[1] = 1; ind[2] = 2;
      val[0] = 1; val[1] = 1; val[2] = 1;

      error = GRBaddconstr(model, 3, ind, val, GRB_LESS_EQUAL, 10.0, "c0");
      if (error) goto QUIT;

      /* Bilinear inequality: x * y <= 2 */

      qrow[0] = 0; qcol[0] = 1; qval[0] = 1.0;

      error = GRBaddqconstr(model, 0, NULL, NULL, 1, qrow, qcol, qval,
                            GRB_LESS_EQUAL, 2.0, "bilinear0");
      if (error) goto QUIT;

      /* Bilinear equality: x * z + y * z == 1 */

      qrow[0] = 0; qcol[0] = 2; qval[0] = 1.0;
      qrow[1] = 1; qcol[1] = 2; qval[1] = 1.0;

      error = GRBaddqconstr(model, 0, NULL, NULL, 2, qrow, qcol, qval,
                            GRB_EQUAL, 1, "bilinear1");
      if (error) goto QUIT;

      /* Optimize model */

      error = GRBoptimize(model);
      if (error) goto QUIT;

      /* Write model to 'bilinear.lp' */

      error = GRBwrite(model, "bilinear.lp");
      if (error) goto QUIT;

      /* Capture solution information */

      error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimstatus);
      if (error) goto QUIT;

      error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &objval);
      if (error) goto QUIT;

      error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, 3, sol);
      if (error) goto QUIT;

      printf("\nOptimization complete\n");
      if (optimstatus == GRB_OPTIMAL) {
        printf("Optimal objective: %.4e\n", objval);

        printf("  x=%.2f, y=%.2f, z=%.2f\n", sol[0], sol[1], sol[2]);
      } else if (optimstatus == GRB_INF_OR_UNBD) {
        printf("Model is infeasible or unbounded\n");
      } else {
        printf("Optimization was stopped early\n");
      }

      /* Now constrain 'x' to be integral and solve again */

      error = GRBsetcharattrelement(model, GRB_CHAR_ATTR_VTYPE, 0, GRB_INTEGER);
      if (error) goto QUIT;

      error = GRBoptimize(model);
      if (error) goto QUIT;

      /* Capture solution information */

      error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimstatus);
      if (error) goto QUIT;

      error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &objval);
      if (error) goto QUIT;

      error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, 3, sol);
      if (error) goto QUIT;

      printf("\nOptimization complete\n");
      if (optimstatus == GRB_OPTIMAL) {
        printf("Optimal objective: %.4e\n", objval);

        printf("  x=%.2f, y=%.2f, z=%.2f\n", sol[0], sol[1], sol[2]);
      } 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 2025, Gurobi Optimization, LLC */

    /* This example formulates and solves the following simple bilinear model:

         maximize    x
         subject to  x + y + z <= 10
                     x * y <= 2          (bilinear inequality)
                     x * z + y * z == 1  (bilinear equality)
                     x, y, z non-negative (x integral in second version)
    */
    #include <cassert>
    #include "gurobi_c++.h"
    using namespace std;

    int
    main(int   argc,
         char *argv[])
    {
      try {
        GRBEnv env = GRBEnv();

        GRBModel model = GRBModel(env);

        // Create variables

        GRBVar x = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "x");
        GRBVar y = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "y");
        GRBVar z = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "z");

        // Set objective

        GRBLinExpr obj = x;
        model.setObjective(obj, GRB_MAXIMIZE);

        // Add linear constraint: x + y + z <= 10

        model.addConstr(x + y + z <= 10, "c0");

        // Add bilinear inequality constraint: x * y <= 2

        model.addQConstr(x*y <= 2, "bilinear0");

        // Add bilinear equality constraint: y * z == 1

        model.addQConstr(x*z + y*z == 1, "bilinear1");

        // Optimize model
        model.optimize();

        cout << x.get(GRB_StringAttr_VarName) << " "
             << x.get(GRB_DoubleAttr_X) << endl;
        cout << y.get(GRB_StringAttr_VarName) << " "
             << y.get(GRB_DoubleAttr_X) << endl;
        cout << z.get(GRB_StringAttr_VarName) << " "
             << z.get(GRB_DoubleAttr_X) << endl;

        // Constrain x to be integral and solve again
        x.set(GRB_CharAttr_VType, GRB_INTEGER);
        model.optimize();

        cout << x.get(GRB_StringAttr_VarName) << " "
             << x.get(GRB_DoubleAttr_X) << endl;
        cout << y.get(GRB_StringAttr_VarName) << " "
             << y.get(GRB_DoubleAttr_X) << endl;
        cout << z.get(GRB_StringAttr_VarName) << " "
             << z.get(GRB_DoubleAttr_X) << endl;

        cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl;

      } catch(GRBException e) {
        cout << "Error code = " << e.getErrorCode() << endl;
        cout << e.getMessage() << endl;
      } catch(...) {
        cout << "Exception during optimization" << endl;
      }

      return 0;
    }

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* This example formulates and solves the following simple bilinear model:

         maximize    x
         subject to  x + y + z <= 10
                     x * y <= 2          (bilinear inequality)
                     x * z + y * z == 1  (bilinear equality)
                     x, y, z non-negative (x integral in second version)
    */

    using System;
    using Gurobi;

    class bilinear_cs
    {
      static void Main()
      {
        try {
          GRBEnv    env   = new GRBEnv("bilinear.log");
          GRBModel  model = new GRBModel(env);

          // Create variables

          GRBVar x = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "x");
          GRBVar y = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "y");
          GRBVar z = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "z");

          // Set objective

          GRBLinExpr obj = x;
          model.SetObjective(obj, GRB.MAXIMIZE);

          // Add linear constraint: x + y + z <= 10

          model.AddConstr(x + y + z <= 10, "c0");

          // Add bilinear inequality: x * y <= 2

          model.AddQConstr(x*y <= 2, "bilinear0");

          // Add bilinear equality: x * z + y * z == 1

          model.AddQConstr(x*z + y*z == 1, "bilinear1");

          // Optimize model

          model.Optimize();

          Console.WriteLine(x.VarName + " " + x.X);
          Console.WriteLine(y.VarName + " " + y.X);
          Console.WriteLine(z.VarName + " " + z.X);

          Console.WriteLine("Obj: " + model.ObjVal + " " + obj.Value);

          x.Set(GRB.CharAttr.VType, GRB.INTEGER);
          model.Optimize();

          Console.WriteLine(x.VarName + " " + x.X);
          Console.WriteLine(y.VarName + " " + y.X);
          Console.WriteLine(z.VarName + " " + z.X);

          Console.WriteLine("Obj: " + model.ObjVal + " " + obj.Value);

          // Dispose of model and env

          model.Dispose();
          env.Dispose();

        } catch (GRBException e) {
          Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
        }
      }
    }

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* This example formulates and solves the following simple bilinear model:

         maximize    x
         subject to  x + y + z <= 10
                     x * y <= 2          (bilinear inequality)
                     x * z + y * z == 1  (bilinear equality)
                     x, y, z non-negative (x integral in second version)
    */

    import com.gurobi.gurobi.*;

    public class Bilinear {
      public static void main(String[] args) {
        try {
          GRBEnv    env   = new GRBEnv("bilinear.log");
          GRBModel  model = new GRBModel(env);

          // Create variables

          GRBVar x = model.addVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "x");
          GRBVar y = model.addVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "y");
          GRBVar z = model.addVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "z");

          // Set objective

          GRBLinExpr obj = new GRBLinExpr();
          obj.addTerm(1.0, x);
          model.setObjective(obj, GRB.MAXIMIZE);

          // Add linear constraint: x + y + z <= 10

          GRBLinExpr expr = new GRBLinExpr();
          expr.addTerm(1.0, x); expr.addTerm(1.0, y); expr.addTerm(1.0, z);
          model.addConstr(expr, GRB.LESS_EQUAL, 10.0, "c0");

          // Add bilinear inequality: x * y <= 2

          GRBQuadExpr qexpr = new GRBQuadExpr();
          qexpr.addTerm(1.0, x, y);
          model.addQConstr(qexpr, GRB.LESS_EQUAL, 2.0, "bilinear0");

          // Add bilinear equality: x * z + y * z == 1

          qexpr = new GRBQuadExpr();
          qexpr.addTerm(1.0, x, z);
          qexpr.addTerm(1.0, y, z);
          model.addQConstr(qexpr, GRB.EQUAL, 1.0, "bilinear1");

          // Optimize model

          model.optimize();

          System.out.println(x.get(GRB.StringAttr.VarName)
                             + " " +x.get(GRB.DoubleAttr.X));
          System.out.println(y.get(GRB.StringAttr.VarName)
                             + " " +y.get(GRB.DoubleAttr.X));
          System.out.println(z.get(GRB.StringAttr.VarName)
                             + " " +z.get(GRB.DoubleAttr.X));

          System.out.println("Obj: " + model.get(GRB.DoubleAttr.ObjVal) + " " +
                             obj.getValue());
          System.out.println();

          // Constrain x to be integral and solve again

          x.set(GRB.CharAttr.VType, GRB.INTEGER);
          model.optimize();

          System.out.println(x.get(GRB.StringAttr.VarName)
                             + " " +x.get(GRB.DoubleAttr.X));
          System.out.println(y.get(GRB.StringAttr.VarName)
                             + " " +y.get(GRB.DoubleAttr.X));
          System.out.println(z.get(GRB.StringAttr.VarName)
                             + " " +z.get(GRB.DoubleAttr.X));

          System.out.println("Obj: " + model.get(GRB.DoubleAttr.ObjVal) + " " +
                             obj.getValue());
          System.out.println();

          // Dispose of model and environment

          model.dispose();
          env.dispose();

        } catch (GRBException e) {
          System.out.println("Error code: " + e.getErrorCode() + ". " +
              e.getMessage());
        }
      }
    }

    function bilinear
    % This example formulates and solves the following simple bilinear model:
    %  maximize    x
    %  subject to  x + y + z <= 10
    %              x * y <= 2         (bilinear inequality)
    %              x * z + y * z = 1  (bilinear equality)
    %              x, y, z non-negative (x integral in second version)

    % Copyright 2025, Gurobi Optimization, LLC

    % Linear constraint matrix
    m.A = sparse([1, 1, 1]);
    m.sense = '<';
    m.rhs = 10;

    % Variable names
    m.varnames = {'x', 'y', 'z'};

    % Objective function max 1.0 * x
    m.obj = [1; 0; 0];
    m.modelsense = 'max';

    % Bilinear inequality constraint: x * y <= 2
    m.quadcon(1).Qrow = 1;
    m.quadcon(1).Qcol = 2;
    m.quadcon(1).Qval = 1.0;
    m.quadcon(1).q = sparse(3,1);
    m.quadcon(1).rhs = 2.0;
    m.quadcon(1).sense = '<';
    m.quadcon(1).name = 'bilinear0';

    % Bilinear equality constraint: x * z + y * z == 1
    m.quadcon(2).Qrow = [1, 2];
    m.quadcon(2).Qcol = [3, 3];
    m.quadcon(2).Qval = [1.0, 1.0];
    m.quadcon(2).q = sparse(3,1);
    m.quadcon(2).rhs = 1.0;
    m.quadcon(2).sense = '=';
    m.quadcon(2).name = 'bilinear1';

    % Solve bilinear model, display solution.
    result = gurobi(m);
    disp(result.x);

    % Constrain 'x' to be integral and solve again
    m.vtype = 'ICC';
    result = gurobi(m);
    disp(result.x);
    end

    #!/usr/bin/env python3

    # Copyright 2025, Gurobi Optimization, LLC

    # This example formulates and solves the following simple bilinear model:
    #  maximize    x
    #  subject to  x + y + z <= 10
    #              x * y <= 2         (bilinear inequality)
    #              x * z + y * z = 1  (bilinear equality)
    #              x, y, z non-negative (x integral in second version)

    import gurobipy as gp
    from gurobipy import GRB

    # Create a new model
    m = gp.Model("bilinear")

    # Create variables
    x = m.addVar(name="x")
    y = m.addVar(name="y")
    z = m.addVar(name="z")

    # Set objective: maximize x
    m.setObjective(1.0 * x, GRB.MAXIMIZE)

    # Add linear constraint: x + y + z <= 10
    m.addConstr(x + y + z <= 10, "c0")

    # Add bilinear inequality constraint: x * y <= 2
    m.addConstr(x * y <= 2, "bilinear0")

    # Add bilinear equality constraint: x * z + y * z == 1
    m.addConstr(x * z + y * z == 1, "bilinear1")

    # Optimize model
    m.optimize()

    m.printAttr("x")

    # Constrain 'x' to be integral and solve again
    x.VType = GRB.INTEGER
    m.optimize()

    m.printAttr("x")

    # Copyright 2025, Gurobi Optimization, LLC
    #
    # This example formulates and solves the following simple bilinear model:
    #  maximize
    #        x
    #  subject to
    #        x + y + z <= 10
    #        x * y <= 2         (bilinear inequality)
    #        x * z + y * z = 1  (bilinear equality)
    #        x, y, z non-negative (x integral in second version)

    library(gurobi)
    library(Matrix)

    model <- list()

    # Linear constraint matrix
    model$A <- matrix(c(1, 1, 1), nrow=1, byrow=T)
    model$rhs <- c(10.0)
    model$sense <- c('<')

    # Variable names
    model$varnames <- c('x', 'y', 'z')

    # Objective function max 1.0 * x
    model$obj <- c(1, 0, 0)
    model$modelsense <- 'max'

    # Bilinear inequality constraint: x * y <= 2
    qc1 <- list()
    qc1$Qc <- spMatrix(3, 3, c(1), c(2), c(1.0))
    qc1$rhs <- 2.0
    qc1$sense <- c('<')
    qc1$name <- 'bilinear0'

    # Bilinear equality constraint: x * z + y * z == 1
    qc2 <- list()
    qc2$Qc <- spMatrix(3, 3, c(1, 2), c(3, 3), c(1.0, 1.0))
    qc2$rhs <- 1.0
    qc2$sense <- c('=')
    qc2$name <- 'bilinear1'

    model$quadcon <- list(qc1, qc2)

    # Solve bilinear model, display solution.
    result <- gurobi(model)
    print(result$x)

    # Constrain 'x' to be integral and solve again
    model$vtype <- c('I', 'C', 'C')
    result <- gurobi(model)
    print(result$x)

    ' Copyright 2025, Gurobi Optimization, LLC */

    ' This example formulates and solves the following simple bilinear model:
    '
    '     maximize    x
    '     subject to  x + y + z <= 10
    '                 x * y <= 2          (bilinear inequality)
    '                 x * z + y * z == 1  (bilinear equality)
    '                 x, y, z non-negative (x integral in second version)

    Imports Gurobi

    Class bilinear_vb
        Shared Sub Main()
            Try
                Dim env As New GRBEnv("bilinear.log")
                Dim model As New GRBModel(env)

                ' Create variables

                Dim x As GRBVar = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "x")
                Dim y As GRBVar = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "y")
                Dim z As GRBVar = model.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "z")

                ' Set objective
                Dim obj As GRBLinExpr = x
                model.SetObjective(obj, GRB.MAXIMIZE)

                ' Add linear constraint: x + y + z <= 10

                model.AddConstr(x + y + z <= 10, "c0")

                ' Add bilinear inequality: x * y <= 2

                model.AddQConstr(x * y <= 2, "bilinear0")

                ' Add bilinear equality: x * z + y * z == 1

                model.AddQConstr(x * z + y * z = 1, "bilinear1")

                ' Optimize model

                model.Optimize()

                Console.WriteLine(x.VarName & " " & x.X)
                Console.WriteLine(y.VarName & " " & y.X)
                Console.WriteLine(z.VarName & " " & z.X)

                Console.WriteLine("Obj: " & model.ObjVal & " " & obj.Value)

                x.Set(GRB.CharAttr.VType, GRB.INTEGER)
                model.Optimize()

                Console.WriteLine(x.VarName & " " & x.X)
                Console.WriteLine(y.VarName & " " & y.X)
                Console.WriteLine(z.VarName & " " & z.X)

                Console.WriteLine("Obj: " & model.ObjVal & " " & obj.Value)

                ' Dispose of model and env

                model.Dispose()

                env.Dispose()
            Catch e As GRBException
                Console.WriteLine("Error code: " & e.ErrorCode & ". " & e.Message)
            End Try

        End Sub
    End Class

Help and Feedback

Press `/` or click to search this documentation | Gurobi website | Gurobi community forum
Go to other Gurobi documentation | Gurobi download | Contact support