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

# Poolsearch Examples

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

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* We find alternative epsilon-optimal solutions to a given knapsack
     * problem by using PoolSearchMode */

    #include <assert.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include "gurobi_c.h"

    #define MAXSTR 128

    int main(void)
    {
      GRBenv   *env   = NULL;
      GRBenv   *menv  = NULL;
      GRBmodel *model = NULL;
      int       error = 0;
      char      buffer[MAXSTR];
      int e, status, nSolutions, prlen;
      double objval, *cval = NULL;
      int *cind = NULL;

      /* Sample data */
      const int groundSetSize = 10;
      double objCoef[10] =
        {32, 32, 15, 15, 6, 6, 1, 1, 1, 1};
      double knapsackCoef[10] =
        {16, 16,  8,  8, 4, 4, 2, 2, 1, 1};
      double Budget = 33;

      /* Create environment */
      error = GRBloadenv(&env, "poolsearch_c.log");
      if (error) goto QUIT;

      /* Create initial model */
      error = GRBnewmodel(env, &model, "poolsearch_c", groundSetSize, NULL,
                          NULL, NULL, NULL, NULL);
      if (error) goto QUIT;

      /* get model environment */
      menv = GRBgetenv(model);
      assert(menv != NULL);

      /* set objective function */
      error = GRBsetdblattrarray(model, "Obj", 0, groundSetSize, objCoef);
      if (error) goto QUIT;

      /* set variable types and names */
      for (e = 0; e < groundSetSize; e++) {
        sprintf(buffer, "El%d", e);
        error = GRBsetcharattrelement(model, "VType", e, GRB_BINARY);
        if (error) goto QUIT;

        error = GRBsetstrattrelement(model, "VarName", e, buffer);
        if (error) goto QUIT;
      }

      /* Make space for constraint data */
      cind = malloc(sizeof(int) * groundSetSize);
      if (!cind) goto QUIT;
      for (e = 0; e < groundSetSize; e++)
        cind[e] = e;

      /* Constraint: limit total number of elements to be picked to be at most
       * Budget */
      sprintf (buffer, "Budget");
      error = GRBaddconstr(model, groundSetSize, cind, knapsackCoef,
                           GRB_LESS_EQUAL, Budget, buffer);
      if (error) goto QUIT;

      /* set global sense for ALL objectives */
      error = GRBsetintattr(model, GRB_INT_ATTR_MODELSENSE, GRB_MAXIMIZE);
      if (error) goto QUIT;

      /* Limit how many solutions to collect */
      error = GRBsetintparam(menv, GRB_INT_PAR_POOLSOLUTIONS, 1024);
      if (error) goto QUIT;

      /* Limit the search space by setting a gap for the worst possible solution that will be accepted */
      error = GRBsetdblparam(menv, GRB_DBL_PAR_POOLGAP, 0.10);
      if (error) goto QUIT;

      /* do a systematic search for the k-best solutions */
      error = GRBsetintparam(menv, GRB_INT_PAR_POOLSEARCHMODE, 2);
      if (error) goto QUIT;

      /* save problem */
      error = GRBwrite(model, "poolsearch_c.lp");
      if (error) goto QUIT;
      error = GRBwrite(model, "poolsearch_c.mps");
      if (error) goto QUIT;

      /* Optimize */
      error = GRBoptimize(model);
      if (error) goto QUIT;

      /* Status checking */
      error = GRBgetintattr(model, "Status", &status);
      if (error) goto QUIT;

      if (status == GRB_INF_OR_UNBD ||
          status == GRB_INFEASIBLE  ||
          status == GRB_UNBOUNDED     ) {
        printf("The model cannot be solved "
               "because it is infeasible or unbounded\n");
        goto QUIT;
      }
      if (status != GRB_OPTIMAL) {
        printf("Optimization was stopped with status %d\n", status);
        goto QUIT;
      }

      /* make space for optimal solution */
      cval = malloc(sizeof(double) * groundSetSize);
      if (!cval) goto QUIT;

      /* Print best selected set */
      error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, groundSetSize, cval);
      if (error) goto QUIT;

      printf("Selected elements in best solution:\n\t");
      for (e = 0; e < groundSetSize; e++) {
        if (cval[e] < .9) continue;
        printf("El%d ", e);
      }

      /* print number of solutions stored */
      error = GRBgetintattr(model, GRB_INT_ATTR_SOLCOUNT, &nSolutions);
      if (error) goto QUIT;
      printf("\nNumber of solutions found: %d\nValues:", nSolutions);

      /* print objective values of alternative solutions */
      prlen = 0;
      for (e = 0; e < nSolutions; e++) {
        error = GRBsetintparam(menv, GRB_INT_PAR_SOLUTIONNUMBER, e);
        if (error) goto QUIT;

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

        prlen += printf(" %g", objval);
        if (prlen >= 75 && e+1 < nSolutions) {
          prlen = printf("\n    ");
        }
      }
      printf("\n");

      /* print fourth best set if available */
      if (nSolutions >= 4) {
        error = GRBsetintparam(menv, GRB_INT_PAR_SOLUTIONNUMBER, 3);
        if (error) goto QUIT;

        /* get the solution vector */
        error = GRBgetdblattrarray(model, GRB_DBL_ATTR_POOLNX, 0, groundSetSize, cval);
        if (error) goto QUIT;

        printf("Selected elements in fourth best solution:\n\t");
        for (e = 0; e < groundSetSize; e++) {
          if (cval[e] < .9) continue;
          printf("El%d ", e);
        }
        printf("\n");
      }

    QUIT:
      if (model != NULL) GRBfreemodel(model);
      if (env != NULL)   GRBfreeenv(env);
      if (cind != NULL)  free(cind);
      if (cval != NULL)  free(cval);
      return error;
    }

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* We find alternative epsilon-optimal solutions to a given knapsack
     * problem by using PoolSearchMode */

    #include "gurobi_c++.h"
    #include <sstream>
    #include <iomanip>
    using namespace std;

    int main(void)
    {
      GRBEnv *env  = 0;
      GRBVar *Elem = 0;
      int e, status, nSolutions;

      try {
        // Sample data
        const int groundSetSize = 10;
        double objCoef[10] =
        {32, 32, 15, 15, 6, 6, 1, 1, 1, 1};
        double knapsackCoef[10] =
        {16, 16,  8,  8, 4, 4, 2, 2, 1, 1};
        double Budget = 33;

        // Create environment
        env = new GRBEnv("poolsearch_c++.log");

        // Create initial model
        GRBModel model = GRBModel(*env);
        model.set(GRB_StringAttr_ModelName, "poolsearch_c++");

        // Initialize decision variables for ground set:
        // x[e] == 1 if element e is chosen
        Elem = model.addVars(groundSetSize, GRB_BINARY);
        model.set(GRB_DoubleAttr_Obj, Elem, objCoef, groundSetSize);

        for (e = 0; e < groundSetSize; e++) {
          ostringstream vname;
          vname << "El" << e;
          Elem[e].set(GRB_StringAttr_VarName, vname.str());
        }

        // Constraint: limit total number of elements to be picked to be at most
        // Budget
        GRBLinExpr lhs;
        lhs = 0;
        for (e = 0; e < groundSetSize; e++) {
          lhs += Elem[e] * knapsackCoef[e];
        }
        model.addConstr(lhs <= Budget, "Budget");

        // set global sense for ALL objectives
        model.set(GRB_IntAttr_ModelSense, GRB_MAXIMIZE);

        // Limit how many solutions to collect
        model.set(GRB_IntParam_PoolSolutions, 1024);

        // Limit the search space by setting a gap for the worst possible solution that will be accepted
        model.set(GRB_DoubleParam_PoolGap, 0.10);

        // do a systematic search for the k-best solutions
        model.set(GRB_IntParam_PoolSearchMode, 2);

        // save problem
        model.write("poolsearch_c++.lp");

        // Optimize
        model.optimize();

        // Status checking
        status = model.get(GRB_IntAttr_Status);

        if (status == GRB_INF_OR_UNBD ||
            status == GRB_INFEASIBLE  ||
            status == GRB_UNBOUNDED     ) {
          cout << "The model cannot be solved " <<
                 "because it is infeasible or unbounded" << endl;
          return 1;
        }
        if (status != GRB_OPTIMAL) {
          cout << "Optimization was stopped with status " << status << endl;
          return 1;
        }

        // Print best selected set
        cout << "Selected elements in best solution:" << endl << "\t";
        for (e = 0; e < groundSetSize; e++) {
          if (Elem[e].get(GRB_DoubleAttr_X) < .9) continue;
          cout << " El" << e;
        }
        cout << endl;

        // Print number of solutions stored
        nSolutions = model.get(GRB_IntAttr_SolCount);
        cout << "Number of solutions found: " << nSolutions << endl;

        // Print objective values of solutions
        for (e = 0; e < nSolutions; e++) {
          model.set(GRB_IntParam_SolutionNumber, e);
          cout << model.get(GRB_DoubleAttr_PoolNObjVal) << " ";
          if (e%15 == 14) cout << endl;
        }
        cout << endl;

        // print fourth best set if available
        if (nSolutions >= 4) {
          model.set(GRB_IntParam_SolutionNumber, 3);

          cout << "Selected elements in fourth best solution:" << endl << "\t";
          for (e = 0; e < groundSetSize; e++) {
            if (Elem[e].get(GRB_DoubleAttr_PoolNX) < .9) continue;
            cout << " El" << e;
          }
          cout << endl;
        }
      }
      catch (GRBException e) {
        cout << "Error code = " << e.getErrorCode() << endl;
        cout << e.getMessage() << endl;
      }
      catch (...) {
        cout << "Exception during optimization" << endl;
      }

      // Free environment/vars
      delete[] Elem;
      delete env;
      return 0;
    }

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* We find alternative epsilon-optimal solutions to a given knapsack
       problem by using PoolSearchMode */

    using System;
    using Gurobi;

    class poolsearch_cs {

      static void Main() {

        try{
          // Sample data
          int groundSetSize = 10;
          double[] objCoef = new double[] {32, 32, 15, 15, 6, 6, 1, 1, 1, 1};
          double[] knapsackCoef = new double[] {16, 16,  8,  8, 4, 4, 2, 2, 1, 1};
          double Budget = 33;
          int e, status, nSolutions;

          // Create environment
          GRBEnv env = new GRBEnv("poolsearch_cs.log");

          // Create initial model
          GRBModel model = new GRBModel(env);
          model.ModelName = "poolsearch_cs";

          // Initialize decision variables for ground set:
          // x[e] == 1 if element e is chosen
          GRBVar[] Elem = model.AddVars(groundSetSize, GRB.BINARY);
          model.Set(GRB.DoubleAttr.Obj, Elem, objCoef);

          for (e = 0; e < groundSetSize; e++) {
            Elem[e].VarName = string.Format("El{0}", e);
          }

          // Constraint: limit total number of elements to be picked to be at most
          // Budget
          GRBLinExpr lhs = new GRBLinExpr();
          for (e = 0; e < groundSetSize; e++) {
            lhs.AddTerm(knapsackCoef[e], Elem[e]);
          }
          model.AddConstr(lhs, GRB.LESS_EQUAL, Budget, "Budget");

          // set global sense for ALL objectives
          model.ModelSense = GRB.MAXIMIZE;

          // Limit how many solutions to collect
          model.Parameters.PoolSolutions = 1024;

          // Limit the search space by setting a gap for the worst possible solution that will be accepted
          model.Parameters.PoolGap = 0.10;

          // do a systematic search for the k-best solutions
          model.Parameters.PoolSearchMode = 2;

          // save problem
          model.Write("poolsearch_cs.lp");

          // Optimize
          model.Optimize();

          // Status checking
          status = model.Status;

          if (status == GRB.Status.INF_OR_UNBD ||
              status == GRB.Status.INFEASIBLE  ||
              status == GRB.Status.UNBOUNDED     ) {
            Console.WriteLine("The model cannot be solved " +
                   "because it is infeasible or unbounded");
            return;
          }
          if (status != GRB.Status.OPTIMAL) {
            Console.WriteLine("Optimization was stopped with status {0}", status);
            return;
          }

          // Print best selected set
          Console.WriteLine("Selected elements in best solution:");
          Console.Write("\t");
          for (e = 0; e < groundSetSize; e++) {
            if (Elem[e].X < .9) continue;
            Console.Write("El{0} ", e);
          }
          Console.WriteLine();

          // Print number of solutions stored
          nSolutions = model.SolCount;
          Console.WriteLine("Number of solutions found: {0}", nSolutions);

          // Print objective values of solutions
          for (e = 0; e < nSolutions; e++) {
            model.Parameters.SolutionNumber = e;
            Console.Write("{0} ", model.PoolNObjVal);
            if (e%15 == 14) Console.WriteLine();
          }
          Console.WriteLine();

          // Print fourth best set if available
          if (nSolutions >= 4) {
            model.Parameters.SolutionNumber = 3;

            Console.WriteLine("Selected elements in fourth best solution:");
            Console.Write("\t");
            for (e = 0; e < groundSetSize; e++) {
              if (Elem[e].PoolNX < .9) continue;
              Console.Write("El{0} ", e);
            }
            Console.WriteLine();
          }

          model.Dispose();
          env.Dispose();
        } catch (GRBException e) {
          Console.WriteLine("Error code: {0}. {1}", e.ErrorCode, e.Message);
        }
      }

    }

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* We find alternative epsilon-optimal solutions to a given knapsack
       problem by using PoolSearchMode */

    import com.gurobi.gurobi.*;

    public class Poolsearch {

      public static void main(String[] args) {

        try{
          // Sample data
          int groundSetSize = 10;
          double objCoef[] = new double[] {32, 32, 15, 15, 6, 6, 1, 1, 1, 1};
          double knapsackCoef[] = new double[] {16, 16,  8,  8, 4, 4, 2, 2, 1, 1};
          double Budget = 33;
          int e, status, nSolutions;

          // Create environment
          GRBEnv env = new GRBEnv("Poolsearch.log");

          // Create initial model
          GRBModel model = new GRBModel(env);
          model.set(GRB.StringAttr.ModelName, "Poolsearch");

          // Initialize decision variables for ground set:
          // x[e] == 1 if element e is chosen
          GRBVar[] Elem = model.addVars(groundSetSize, GRB.BINARY);
          model.set(GRB.DoubleAttr.Obj, Elem, objCoef, 0, groundSetSize);

          for (e = 0; e < groundSetSize; e++) {
            Elem[e].set(GRB.StringAttr.VarName, "El" + String.valueOf(e));
          }

          // Constraint: limit total number of elements to be picked to be at most
          // Budget
          GRBLinExpr lhs = new GRBLinExpr();
          for (e = 0; e < groundSetSize; e++) {
            lhs.addTerm(knapsackCoef[e], Elem[e]);
          }
          model.addConstr(lhs, GRB.LESS_EQUAL, Budget, "Budget");

          // set global sense for ALL objectives
          model.set(GRB.IntAttr.ModelSense, GRB.MAXIMIZE);

          // Limit how many solutions to collect
          model.set(GRB.IntParam.PoolSolutions, 1024);

          // Limit the search space by setting a gap for the worst possible solution that will be accepted
          model.set(GRB.DoubleParam.PoolGap, 0.10);

          // do a systematic search for the k-best solutions
          model.set(GRB.IntParam.PoolSearchMode, 2);

          // save problem
          model.write("Poolsearch.lp");

          // Optimize
          model.optimize();

          // Status checking
          status = model.get(GRB.IntAttr.Status);

          if (status == GRB.INF_OR_UNBD ||
              status == GRB.INFEASIBLE  ||
              status == GRB.UNBOUNDED     ) {
            System.out.println("The model cannot be solved " +
                   "because it is infeasible or unbounded");
            System.exit(1);
          }
          if (status != GRB.OPTIMAL) {
            System.out.println("Optimization was stopped with status " + status);
            System.exit(1);
          }

          // Print best selected set
          System.out.println("Selected elements in best solution:");
          System.out.print("\t");
          for (e = 0; e < groundSetSize; e++) {
            if (Elem[e].get(GRB.DoubleAttr.X) < .9) continue;
            System.out.print(" El" + e);
          }
          System.out.println();

          // Print number of solutions stored
          nSolutions = model.get(GRB.IntAttr.SolCount);
          System.out.println("Number of solutions found: " + nSolutions);

          // Print objective values of solutions
          for (e = 0; e < nSolutions; e++) {
            model.set(GRB.IntParam.SolutionNumber, e);
            System.out.print(model.get(GRB.DoubleAttr.PoolNObjVal) +  " ");
            if (e%15 == 14) System.out.println();
          }
          System.out.println();

          // print fourth best set if available
          if (nSolutions >= 4) {
            model.set(GRB.IntParam.SolutionNumber, 3);

            System.out.println("Selected elements in fourth best solution:");
            System.out.print("\t");
            for (e = 0; e < groundSetSize; e++) {
              if (Elem[e].get(GRB.DoubleAttr.PoolNX) < .9) continue;
              System.out.print(" El" + e);
            }
            System.out.println();
          }

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

    }

    function poolsearch()

    % Copyright 2025, Gurobi Optimization, LLC
    %
    % We find alternative epsilon-optimal solutions to a given knapsack
    % problem by using PoolSearchMode

    % define primitive data
    groundSetSize = 10;
    objCoef       = [32; 32; 15; 15; 6; 6; 1; 1; 1; 1];
    knapsackCoef  = [16, 16,  8,  8, 4, 4, 2, 2, 1, 1];
    Budget        = 33;

    % Initialize model
    model.modelsense  = 'max';
    model.modelname   = 'poolsearch';

    % Set variables
    model.obj         = objCoef;
    model.vtype       = repmat('B', groundSetSize, 1);
    model.lb          = zeros(groundSetSize, 1);
    model.ub          = ones(groundSetSize, 1);
    for j = 1:groundSetSize
        model.varnames{j} = sprintf('El%d', j);
    end

    % Build constraint matrix
    model.A           = sparse(knapsackCoef);
    model.rhs         = Budget;
    model.sense       = '<';
    model.constrnames = {'Budget'};

    % Set poolsearch parameters
    params.PoolSolutions  = 1024;
    params.PoolGap        = 0.10;
    params.PoolSearchMode = 2;

    % Save problem
    gurobi_write(model, 'poolsearch_m.lp');

    % Optimize
    result = gurobi(model, params);

    % Capture solution information
    if ~strcmp(result.status, 'OPTIMAL')
        fprintf('Optimization finished with status %s, quit now\n', result.status);
        return;
    end

    % Print best solution
    fprintf('Selected elements in best solution:\n');
    for j = 1:groundSetSize
        if result.x(j) >= 0.9
            fprintf('%s ', model.varnames{j});
        end
    end
    fprintf('\n');

    % Print all solution objectives and best furth solution
    if isfield(result, 'pool') && ~isempty(result.pool)
        solcount = length(result.pool);
        fprintf('Number of solutions found: %d\n', solcount);
        fprintf('Objective values for all %d solutions:\n', solcount);
        for k = 1:solcount
            fprintf('%g ', result.pool(k).objval);
        end
        fprintf('\n');
        if solcount >= 4
            fprintf('Selected elements in fourth best solution:\n');
            for k = 1:groundSetSize
                if result.pool(4).poolnx(k) >= 0.9
                    fprintf(' %s', model.varnames{k});
                end
            end
            fprintf('\n');
        end
    else
        fprintf('Number of solutions found: 1\n');
        fprintf('Solution 1 has objective: %g \n', result.objval);
    end

    #!/usr/bin/env python3

    # Copyright 2025, Gurobi Optimization, LLC

    # We find alternative epsilon-optimal solutions to a given knapsack
    # problem by using PoolSearchMode

    import gurobipy as gp
    from gurobipy import GRB
    import sys

    try:
        # Sample data
        Groundset = range(10)
        objCoef = [32, 32, 15, 15, 6, 6, 1, 1, 1, 1]
        knapsackCoef = [16, 16, 8, 8, 4, 4, 2, 2, 1, 1]
        Budget = 33

        # Create initial model
        model = gp.Model("poolsearch")

        # Create dicts for tupledict.prod() function
        objCoefDict = dict(zip(Groundset, objCoef))
        knapsackCoefDict = dict(zip(Groundset, knapsackCoef))

        # Initialize decision variables for ground set:
        # x[e] == 1 if element e is chosen
        Elem = model.addVars(Groundset, vtype=GRB.BINARY, name="El")

        # Set objective function
        model.ModelSense = GRB.MAXIMIZE
        model.setObjective(Elem.prod(objCoefDict))

        # Constraint: limit total number of elements to be picked to be at most
        # Budget
        model.addConstr(Elem.prod(knapsackCoefDict) <= Budget, name="Budget")

        # Limit how many solutions to collect
        model.setParam(GRB.Param.PoolSolutions, 1024)
        # Limit the search space by setting a gap for the worst possible solution
        # that will be accepted
        model.setParam(GRB.Param.PoolGap, 0.10)
        # do a systematic search for the k-best solutions
        model.setParam(GRB.Param.PoolSearchMode, 2)

        # save problem
        model.write("poolsearch.lp")

        # Optimize
        model.optimize()

        model.setParam(GRB.Param.OutputFlag, 0)

        # Status checking
        status = model.Status
        if status in (GRB.INF_OR_UNBD, GRB.INFEASIBLE, GRB.UNBOUNDED):
            print("The model cannot be solved because it is infeasible or unbounded")
            sys.exit(1)

        if status != GRB.OPTIMAL:
            print(f"Optimization was stopped with status {status}")
            sys.exit(1)

        # Print best selected set
        print("Selected elements in best solution:")
        print("\t", end="")
        for e in Groundset:
            if Elem[e].X > 0.9:
                print(f" El{e}", end="")
        print("")

        # Print number of solutions stored
        nSolutions = model.SolCount
        print(f"Number of solutions found: {nSolutions}")

        # Print objective values of solutions
        for e in range(nSolutions):
            model.setParam(GRB.Param.SolutionNumber, e)
            print(f"{model.PoolNObjVal:g} ", end="")
            if e % 15 == 14:
                print("")
        print("")

        # print fourth best set if available
        if nSolutions >= 4:
            model.setParam(GRB.Param.SolutionNumber, 3)

            print("Selected elements in fourth best solution:")
            print("\t", end="")
            for e in Groundset:
                if Elem[e].PoolNX > 0.9:
                    print(f" El{e}", end="")
            print("")

    except gp.GurobiError as e:
        print(f"Gurobi error {e.errno}: {e.message}")

    except AttributeError as e:
        print(f"Encountered an attribute error: {e}")

    # Copyright 2025, Gurobi Optimization, LLC
    #
    # We find alternative epsilon-optimal solutions to a given knapsack
    # problem by using PoolSearchMode

    library(Matrix)
    library(gurobi)

    # define primitive data
    groundSetSize <- 10
    objCoef       <- c(32, 32, 15, 15, 6, 6, 1, 1, 1, 1)
    knapsackCoef  <- c(16, 16,  8,  8, 4, 4, 2, 2, 1, 1)
    Budget        <- 33

    # Initialize model
    model             <- list()
    model$modelsense  <- 'max'
    model$modelname   <- 'poolsearch'

    # Set variables
    model$obj         <- objCoef
    model$vtype       <- 'B'
    model$lb          <- 0
    model$ub          <- 1
    model$varnames    <- sprintf('El%d', seq(1,groundSetSize))

    # Build constraint matrix
    model$A           <- spMatrix(1, groundSetSize,
                                  i = rep(1,groundSetSize),
                                  j = 1:groundSetSize,
                                  x = knapsackCoef)
    model$rhs         <- c(Budget)
    model$sense       <- c('<')
    model$constrnames <- c('Budget')

    # Set poolsearch parameters
    params                <- list()
    params$PoolSolutions  <- 1024
    params$PoolGap        <- 0.10
    params$PoolSearchMode <- 2

    # Save problem
    gurobi_write(model, 'poolsearch_R.lp')

    # Optimize
    result <- gurobi(model, params)

    # Capture solution information
    if (result$status != 'OPTIMAL') {
      cat('Optimization finished with status', result$status, '\n')
      stop('Stop now\n')
    }

    # Print best solution
    cat('Selected elements in best solution:\n')
    cat(model$varnames[which(result$x>=0.9)],'\n')

    # Print all solution objectives and best furth solution
    if ('pool' %in% names(result)) {
      solcount <- length(result$pool)
      cat('Number of solutions found:', solcount, '\n')
      cat('Objective values for first', solcount, 'solutions:\n')
      for (k in 1:solcount) {
        cat(result$pool[[k]]$objval,' ',sep='')
      }
      cat('\n')
      if (solcount >= 4) {
        cat('Selected elements in fourth best solution:\n')
        cat(model$varnames[which(result$pool[[4]]$poolnx >= 0.9)], '\n')
      }
    } else {
      solcount <- 1
      cat('Number of solutions found:', solcount, '\n')
      cat('Solution 1 has objective:', result$objval, '\n')
    }

    # Clean up
    rm(model, params, result)

    ' Copyright 2025, Gurobi Optimization, LLC

    ' We find alternative epsilon-optimal solutions to a given knapsack
    ' problem by using PoolSearchMode

    Imports Gurobi

    Class poolsearch_vb

        Shared Sub Main()

            Try

                'Sample data
                Dim groundSetSize As Integer = 10

                Dim objCoef As Double() = New Double() { _
                    32, 32, 15, 15, 6, 6, 1, 1, 1, 1}

                Dim knapsackCoef As Double() = New Double() { _
                    16, 16, 8, 8, 4, 4, 2, 2, 1, 1}

                Dim Budget As Double = 33
                Dim e As Integer, status As Integer, nSolutions As Integer

                ' Create environment
                Dim env As New GRBEnv("poolsearch_vb.log")

                ' Create initial model
                Dim model As New GRBModel(env)
                model.ModelName = "poolsearch_vb"

                ' Initialize decision variables for ground set:
                ' x[e] == k if element e is chosen k-times.
                Dim Elem As GRBVar() = model.AddVars(groundSetSize, GRB.BINARY)
                model.[Set](GRB.DoubleAttr.Obj, Elem, objCoef, 0, groundSetSize)

                For e = 0 To groundSetSize - 1
                    Elem(e).VarName = String.Format("El{0}", e)
                Next

                ' Constraint: limit total number of elements to be picked to be at most Budget
                Dim lhs As New GRBLinExpr()
                For e = 0 To groundSetSize - 1
                    lhs.AddTerm(knapsackCoef(e), Elem(e))
                Next
                model.AddConstr(lhs, GRB.LESS_EQUAL, Budget, "Budget")

                ' set global sense for ALL objectives
                model.ModelSense = GRB.MAXIMIZE

                ' Limit how many solutions to collect
                model.Parameters.PoolSolutions = 1024

                ' Limit how many solutions to collect
                model.Parameters.PoolGap = 0.1

                ' Limit how many solutions to collect
                model.Parameters.PoolSearchMode = 2

                ' save problem
                model.Write("poolsearch_vb.lp")

                ' Optimize
                model.Optimize()

                ' Status checking
                status = model.Status

                If status = GRB.Status.INF_OR_UNBD OrElse _
                   status = GRB.Status.INFEASIBLE OrElse _
                   status = GRB.Status.UNBOUNDED Then
                    Console.WriteLine("The model cannot be solved because it is infeasible or unbounded")
                    Return
                End If
                If status <> GRB.Status.OPTIMAL Then
                    Console.WriteLine("Optimization was stopped with status {0}", status)
                    Return
                End If

                ' Print best selected set
                Console.WriteLine("Selected elements in best solution:")
                Console.Write(vbTab)
                For e = 0 To groundSetSize - 1
                    If Elem(e).X < 0.9 Then
                        Continue For
                    End If
                    Console.Write("El{0} ", e)
                Next
                Console.WriteLine()

                ' Print number of solutions stored
                nSolutions = model.SolCount
                Console.WriteLine("Number of solutions found: ", nSolutions)

                ' Print objective values of solutions
                For e = 0 To nSolutions - 1
                    model.Parameters.SolutionNumber = e
                    Console.Write("{0} ", model.PoolNObjVal)
                    If e Mod 15 = 14 Then
                        Console.WriteLine()
                    End If
                Next
                Console.WriteLine()

                model.Dispose()
                env.Dispose()

            Catch e As GRBException
                Console.WriteLine("Error code: {0}. {1}", 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