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

# Fixanddive Examples

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

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* Implement a simple MIP heuristic.  Relax the model,
       sort variables based on fractionality, and fix the 25% of
       the fractional variables that are closest to integer variables.
       Repeat until either the relaxation is integer feasible or
       linearly infeasible. */

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

    typedef struct
    {
      int index;
      double X;
    }
    var_t ;

    int vcomp(const void* v1, const void* v2);

    int
    main(int   argc,
         char *argv[])
    {
      GRBenv   *env   = NULL, *modelenv = NULL;
      GRBmodel *model = NULL;
      int       error = 0;
      int       j, iter, nfix;
      int       numvars, numintvars, numfractional;
      int      *intvars = NULL;
      int       status;
      char      vtype, *vname;
      double    sol, obj, fixval;
      var_t    *fractional = NULL;

      if (argc < 2)
      {
        fprintf(stderr, "Usage: fixanddive_c filename\n");
        exit(1);
      }

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

      /* Read model */
      error = GRBreadmodel(env, argv[1], &model);
      if (error) goto QUIT;

      /* Collect integer variables and relax them */
      error = GRBgetintattr(model, "NumVars", &numvars);
      if (error) goto QUIT;
      error = GRBgetintattr(model, "NumIntVars", &numintvars);
      if (error) goto QUIT;
      intvars = malloc(sizeof(int) * numintvars);
      if (!intvars) goto QUIT;
      fractional = malloc(sizeof(var_t) * numintvars);
      if (!fractional) goto QUIT;
      numfractional = 0;
      for (j = 0; j < numvars; j++)
      {
        error = GRBgetcharattrelement(model, "VType", j, &vtype);
        if (error) goto QUIT;
        if (vtype != GRB_CONTINUOUS)
        {
          intvars[numfractional++] = j;
          error = GRBsetcharattrelement(model, "VType", j, GRB_CONTINUOUS);
          if (error) goto QUIT;
        }
      }

      modelenv = GRBgetenv(model);
      assert(modelenv != NULL);
      error = GRBsetintparam(modelenv, "OutputFlag", 0);
      if (error) goto QUIT;
      error = GRBoptimize(model);
      if (error) goto QUIT;

      /* Perform multiple iterations. In each iteration, identify the first
         quartile of integer variables that are closest to an integer value
         in the relaxation, fix them to the nearest integer, and repeat. */

      for (iter = 0; iter < 1000; ++iter)
      {

        /* create a list of fractional variables, sorted in order of
           increasing distance from the relaxation solution to the nearest
           integer value */

        numfractional = 0;
        for (j = 0; j < numintvars; ++j)
        {
          error = GRBgetdblattrelement(model, "X", intvars[j], &sol);
          if (error) goto QUIT;
          if (fabs(sol - floor(sol + 0.5)) > 1e-5)
          {
            fractional[numfractional].index = intvars[j];
            fractional[numfractional++].X = sol;
          }
        }

        error = GRBgetdblattr(model, "ObjVal", &obj);
        if (error) goto QUIT;
        printf("Iteration %i, obj %f, fractional %i\n",
               iter, obj, numfractional);

        if (numfractional == 0)
        {
          printf("Found feasible solution - objective %f\n", obj);
          break;
        }

        /* Fix the first quartile to the nearest integer value */
        qsort(fractional, numfractional, sizeof(var_t), vcomp);
        nfix = numfractional / 4;
        nfix = (nfix > 1) ? nfix : 1;
        for (j = 0; j < nfix; ++j)
        {
          fixval = floor(fractional[j].X + 0.5);
          error = GRBsetdblattrelement(model, "LB", fractional[j].index, fixval);
          if (error) goto QUIT;
          error = GRBsetdblattrelement(model, "UB", fractional[j].index, fixval);
          if (error) goto QUIT;
          error = GRBgetstrattrelement(model, "VarName",
                                       fractional[j].index, &vname);
          if (error) goto QUIT;
          printf("  Fix %s to %f ( rel %f )\n", vname, fixval, fractional[j].X);
        }

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

        /* Check optimization result */

        error = GRBgetintattr(model, "Status", &status);
        if (error) goto QUIT;
        if (status != GRB_OPTIMAL)
        {
          printf("Relaxation is infeasible\n");
          break;
        }
      }

    QUIT:

      /* Error reporting */

      if (error)
      {
        printf("ERROR: %s\n", GRBgeterrormsg(env));
        exit(1);
      }

      /* Free data */

      free(intvars);
      free(fractional);

      /* Free model */

      GRBfreemodel(model);

      /* Free environment */

      GRBfreeenv(env);

      return 0;
    }

    int vcomp(const void* v1, const void* v2)
    {
      double sol1, sol2, frac1, frac2;
      sol1 = fabs(((var_t *)v1)->X);
      sol2 = fabs(((var_t *)v2)->X);
      frac1 = fabs(sol1 - floor(sol1 + 0.5));
      frac2 = fabs(sol2 - floor(sol2 + 0.5));
      return (frac1 < frac2) ? -1 : ((frac1 == frac2) ? 0 : 1);
    }

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* Implement a simple MIP heuristic.  Relax the model,
       sort variables based on fractionality, and fix the 25% of
       the fractional variables that are closest to integer variables.
       Repeat until either the relaxation is integer feasible or
       linearly infeasible. */

    #include "gurobi_c++.h"
    #include <algorithm>
    #include <cmath>
    #include <deque>
    using namespace std;

    bool vcomp(GRBVar*, GRBVar*);

    int
    main(int argc,
         char *argv[])
    {
      if (argc < 2)
      {
        cout << "Usage: fixanddive_c++ filename" << endl;
        return 1;
      }

      GRBEnv* env = 0;
      GRBVar* x = 0;
      try
      {
        // Read model
        env = new GRBEnv();
        GRBModel model = GRBModel(*env, argv[1]);

        // Collect integer variables and relax them
        // Note that we use GRBVar* to copy variables
        deque<GRBVar*> intvars;
        x = model.getVars();
        for (int j = 0; j < model.get(GRB_IntAttr_NumVars); ++j)
        {
          if (x[j].get(GRB_CharAttr_VType) != GRB_CONTINUOUS)
          {
            intvars.push_back(&x[j]);
            x[j].set(GRB_CharAttr_VType, GRB_CONTINUOUS);
          }
        }

        model.set(GRB_IntParam_OutputFlag, 0);
        model.optimize();

        // Perform multiple iterations. In each iteration, identify the first
        // quartile of integer variables that are closest to an integer value
        // in the relaxation, fix them to the nearest integer, and repeat.

        for (int iter = 0; iter < 1000; ++iter)
        {

          // create a list of fractional variables, sorted in order of
          // increasing distance from the relaxation solution to the nearest
          // integer value

          deque<GRBVar*> fractional;
          for (size_t j = 0; j < intvars.size(); ++j)
          {
            double sol = fabs(intvars[j]->get(GRB_DoubleAttr_X));
            if (fabs(sol - floor(sol + 0.5)) > 1e-5)
            {
              fractional.push_back(intvars[j]);
            }
          }

          cout << "Iteration " << iter << ", obj " <<
          model.get(GRB_DoubleAttr_ObjVal) << ", fractional " <<
          fractional.size() << endl;

          if (fractional.size() == 0)
          {
            cout << "Found feasible solution - objective " <<
            model.get(GRB_DoubleAttr_ObjVal) << endl;
            break;
          }

          // Fix the first quartile to the nearest integer value
          sort(fractional.begin(), fractional.end(), vcomp);
          int nfix = (int) fractional.size() / 4;
          nfix = (nfix > 1) ? nfix : 1;
          for (int i = 0; i < nfix; ++i)
          {
            GRBVar* v = fractional[i];
            double fixval = floor(v->get(GRB_DoubleAttr_X) + 0.5);
            v->set(GRB_DoubleAttr_LB, fixval);
            v->set(GRB_DoubleAttr_UB, fixval);
            cout << "  Fix " << v->get(GRB_StringAttr_VarName) << " to " <<
            fixval << " ( rel " << v->get(GRB_DoubleAttr_X) << " )" <<
            endl;
          }

          model.optimize();

          // Check optimization result

          if (model.get(GRB_IntAttr_Status) != GRB_OPTIMAL)
          {
            cout << "Relaxation is infeasible" << endl;
            break;
          }
        }

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

      delete[] x;
      delete env;
      return 0;
    }

    bool vcomp(GRBVar* v1,
               GRBVar* v2)
    {
      double sol1 = fabs(v1->get(GRB_DoubleAttr_X));
      double sol2 = fabs(v2->get(GRB_DoubleAttr_X));
      double frac1 = fabs(sol1 - floor(sol1 + 0.5));
      double frac2 = fabs(sol2 - floor(sol2 + 0.5));
      return (frac1 < frac2);
    }

    /* Copyright 2025, Gurobi Optimization, LLC */

    /* Implement a simple MIP heuristic.  Relax the model,
       sort variables based on fractionality, and fix the 25% of
       the fractional variables that are closest to integer variables.
       Repeat until either the relaxation is integer feasible or
       linearly infeasible. */

    using System;
    using System.Collections.Generic;
    using Gurobi;

    class fixanddive_cs
    {
      // Comparison class used to sort variable list based on relaxation
      // fractionality

      class FractionalCompare : IComparer<GRBVar>
      {
        public int Compare(GRBVar v1, GRBVar v2)
        {
          try {
            double sol1 = Math.Abs(v1.X);
            double sol2 = Math.Abs(v2.X);
            double frac1 = Math.Abs(sol1 - Math.Floor(sol1 + 0.5));
            double frac2 = Math.Abs(sol2 - Math.Floor(sol2 + 0.5));
            if (frac1 < frac2) {
              return -1;
            } else if (frac1 > frac2) {
              return 1;
            } else {
              return 0;
            }
          } catch (GRBException e) {
            Console.WriteLine("Error code: " + e.ErrorCode + ". " +
                e.Message);
          }
          return 0;
        }
      }

      static void Main(string[] args)
      {
        if (args.Length < 1) {
          Console.Out.WriteLine("Usage: fixanddive_cs filename");
          return;
        }

        try {
          // Read model
          GRBEnv env = new GRBEnv();
          GRBModel model = new GRBModel(env, args[0]);

          // Collect integer variables and relax them
          List<GRBVar> intvars = new List<GRBVar>();
          foreach (GRBVar v in model.GetVars()) {
            if (v.VType != GRB.CONTINUOUS) {
              intvars.Add(v);
              v.VType = GRB.CONTINUOUS;
            }
          }

          model.Parameters.OutputFlag = 0;
          model.Optimize();

          // Perform multiple iterations. In each iteration, identify the first
          // quartile of integer variables that are closest to an integer value
          // in the relaxation, fix them to the nearest integer, and repeat.

          for (int iter = 0; iter < 1000; ++iter) {

            // create a list of fractional variables, sorted in order of
            // increasing distance from the relaxation solution to the nearest
            // integer value

            List<GRBVar> fractional = new List<GRBVar>();
            foreach (GRBVar v in intvars) {
              double sol = Math.Abs(v.X);
              if (Math.Abs(sol - Math.Floor(sol + 0.5)) > 1e-5) {
                fractional.Add(v);
              }
            }

            Console.WriteLine("Iteration " + iter + ", obj " +
                model.ObjVal + ", fractional " + fractional.Count);

            if (fractional.Count == 0) {
              Console.WriteLine("Found feasible solution - objective " +
                  model.ObjVal);
              break;
            }

            // Fix the first quartile to the nearest integer value

            fractional.Sort(new FractionalCompare());
            int nfix = Math.Max(fractional.Count / 4, 1);
            for (int i = 0; i < nfix; ++i) {
              GRBVar v = fractional[i];
              double fixval = Math.Floor(v.X + 0.5);
              v.LB = fixval;
              v.UB = fixval;
              Console.WriteLine("  Fix " + v.VarName +
                  " to " + fixval + " ( rel " + v.X + " )");
            }

            model.Optimize();

            // Check optimization result

            if (model.Status != GRB.Status.OPTIMAL) {
              Console.WriteLine("Relaxation is infeasible");
              break;
            }
          }

          // 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 */

    /* Implement a simple MIP heuristic.  Relax the model,
     sort variables based on fractionality, and fix the 25% of
     the fractional variables that are closest to integer variables.
     Repeat until either the relaxation is integer feasible or
     linearly infeasible. */

    import com.gurobi.gurobi.*;
    import java.util.*;

    public class Fixanddive {
      public static void main(String[] args) {

        // Comparison class used to sort variable list based on relaxation
        // fractionality

        class FractionalCompare implements Comparator<GRBVar> {
          public int compare(GRBVar v1, GRBVar v2) {
            try {
              double sol1 = Math.abs(v1.get(GRB.DoubleAttr.X));
              double sol2 = Math.abs(v2.get(GRB.DoubleAttr.X));
              double frac1 = Math.abs(sol1 - Math.floor(sol1 + 0.5));
              double frac2 = Math.abs(sol2 - Math.floor(sol2 + 0.5));
              if (frac1 < frac2) {
                return -1;
              } else if (frac1 == frac2) {
                return 0;
              } else {
                return 1;
              }
            } catch (GRBException e) {
              System.out.println("Error code: " + e.getErrorCode() + ". " +
                  e.getMessage());
            }
            return 0;
          }
        }

        if (args.length < 1) {
          System.out.println("Usage: java Fixanddive filename");
          System.exit(1);
        }

        try {
          // Read model
          GRBEnv env = new GRBEnv();
          GRBModel model = new GRBModel(env, args[0]);

          // Collect integer variables and relax them
          ArrayList<GRBVar> intvars = new ArrayList<GRBVar>();
          for (GRBVar v : model.getVars()) {
            if (v.get(GRB.CharAttr.VType) != GRB.CONTINUOUS) {
              intvars.add(v);
              v.set(GRB.CharAttr.VType, GRB.CONTINUOUS);
            }
          }

          model.set(GRB.IntParam.OutputFlag, 0);
          model.optimize();

          // Perform multiple iterations. In each iteration, identify the first
          // quartile of integer variables that are closest to an integer value
          // in the relaxation, fix them to the nearest integer, and repeat.

          for (int iter = 0; iter < 1000; ++iter) {

            // create a list of fractional variables, sorted in order of
            // increasing distance from the relaxation solution to the nearest
            // integer value

            ArrayList<GRBVar> fractional = new ArrayList<GRBVar>();
            for (GRBVar v : intvars) {
              double sol = Math.abs(v.get(GRB.DoubleAttr.X));
              if (Math.abs(sol - Math.floor(sol + 0.5)) > 1e-5) {
                fractional.add(v);
              }
            }

            System.out.println("Iteration " + iter + ", obj " +
                model.get(GRB.DoubleAttr.ObjVal) + ", fractional " +
                fractional.size());

            if (fractional.size() == 0) {
              System.out.println("Found feasible solution - objective " +
                  model.get(GRB.DoubleAttr.ObjVal));
              break;
            }

            // Fix the first quartile to the nearest integer value

            Collections.sort(fractional, new FractionalCompare());
            int nfix = Math.max(fractional.size() / 4, 1);
            for (int i = 0; i < nfix; ++i) {
              GRBVar v = fractional.get(i);
              double fixval = Math.floor(v.get(GRB.DoubleAttr.X) + 0.5);
              v.set(GRB.DoubleAttr.LB, fixval);
              v.set(GRB.DoubleAttr.UB, fixval);
              System.out.println("  Fix " + v.get(GRB.StringAttr.VarName) +
                  " to " + fixval + " ( rel " + v.get(GRB.DoubleAttr.X) + " )");
            }

            model.optimize();

            // Check optimization result

            if (model.get(GRB.IntAttr.Status) != GRB.Status.OPTIMAL) {
              System.out.println("Relaxation is infeasible");
              break;
            }
          }

          // Dispose of model and environment
          model.dispose();
          env.dispose();

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

    }

    function fixanddive(filename)
    %
    % Copyright 2025, Gurobi Optimization, LLC
    %
    % Implement a simple MIP heuristic.  Relax the model,
    % sort variables based on fractionality, and fix the 25% of
    % the fractional variables that are closest to integer variables.
    % Repeat until either the relaxation is integer feasible or
    % linearly infeasible.

    % Read model
    fprintf('Reading model %s\n', filename);

    model = gurobi_read(filename);
    cols = size(model.A, 2);
    ivars = find(model.vtype ~= 'C');

    if length(ivars) <= 0
        fprintf('All variables of the model are continuous, nothing to do\n');
        return;
    end

    % save vtype and set all variables to continuous
    vtype = model.vtype;
    model.vtype = repmat('C', cols, 1);

    params.OutputFlag = 0;

    result = gurobi(model, params);

    % Perform multiple iterations. In each iteration, identify the first
    % quartile of integer variables that are closest to an integer value
    % in the relaxation, fix them to the nearest integer, and repeat.

    frac = zeros(cols, 1);
    for iter = 1:1000
        % See if status is optimal
        if ~strcmp(result.status, 'OPTIMAL')
            fprintf('Model status is %s\n', result.status);
            fprintf('Can not keep fixing variables\n');
            break;
        end
        % collect fractionality of integer variables
        fracs = 0;
        for j = 1:cols
            if vtype(j) == 'C'
                frac(j) = 1; % indicating not integer variable
            else
                t = result.x(j);
                t = t - floor(t);
                if t > 0.5
                    t = t - 0.5;
                end
                if t > 1e-5
                    frac(j) = t;
                    fracs = fracs + 1;
                else
                    frac(j) = 1; % indicating not fractional
                end
            end
        end

        fprintf('Iteration %d, obj %g, fractional %d\n', iter, result.objval, fracs);

        if fracs == 0
            fprintf('Found feasible solution - objective %g\n', result.objval);
            break;
        end

        % sort variables based on fractionality
        [~, I] = sort(frac);

        % fix the first quartile to the nearest integer value
        nfix = max(fracs/4, 1);
        for i = 1:nfix
            j = I(i);
            t = floor(result.x(j) + 0.5);
            model.lb(j) = t;
            model.ub(j) = t;
        end

        % use warm start basis and reoptimize
        model.vbasis = result.vbasis;
        model.cbasis = result.cbasis;
        result = gurobi(model, params);
    end

    #!/usr/bin/env python3

    # Copyright 2025, Gurobi Optimization, LLC

    # Implement a simple MIP heuristic.  Relax the model,
    # sort variables based on fractionality, and fix the 25% of
    # the fractional variables that are closest to integer variables.
    # Repeat until either the relaxation is integer feasible or
    # linearly infeasible.

    import sys
    import gurobipy as gp
    from gurobipy import GRB

    # Key function used to sort variables based on relaxation fractionality

    def sortkey(v1):
        sol = v1.X
        return abs(sol - int(sol + 0.5))

    if len(sys.argv) < 2:
        print("Usage: fixanddive.py filename")
        sys.exit(0)

    # Read model

    model = gp.read(sys.argv[1])

    # Collect integer variables and relax them
    intvars = []
    for v in model.getVars():
        if v.VType != GRB.CONTINUOUS:
            intvars += [v]
            v.VType = GRB.CONTINUOUS

    model.Params.OutputFlag = 0

    model.optimize()

    # Perform multiple iterations.  In each iteration, identify the first
    # quartile of integer variables that are closest to an integer value in the
    # relaxation, fix them to the nearest integer, and repeat.

    for iter in range(1000):
        # create a list of fractional variables, sorted in order of increasing
        # distance from the relaxation solution to the nearest integer value

        fractional = []
        for v in intvars:
            sol = v.X
            if abs(sol - int(sol + 0.5)) > 1e-5:
                fractional += [v]

        fractional.sort(key=sortkey)

        print(f"Iteration {iter}, obj {model.ObjVal:g}, fractional {len(fractional)}")

        if len(fractional) == 0:
            print(f"Found feasible solution - objective {model.ObjVal:g}")
            break

        # Fix the first quartile to the nearest integer value
        nfix = max(int(len(fractional) / 4), 1)
        for i in range(nfix):
            v = fractional[i]
            fixval = int(v.X + 0.5)
            v.LB = fixval
            v.UB = fixval
            print(f"  Fix {v.VarName} to {fixval:g} (rel {v.X:g})")

        model.optimize()

        # Check optimization result

        if model.Status != GRB.OPTIMAL:
            print("Relaxation is infeasible")
            break

    # Copyright 2025, Gurobi Optimization, LLC
    #
    # Implement a simple MIP heuristic.  Relax the model,
    # sort variables based on fractionality, and fix the 25% of
    # the fractional variables that are closest to integer variables.
    # Repeat until either the relaxation is integer feasible or
    # linearly infeasible.

    library(Matrix)
    library(gurobi)

    args <- commandArgs(trailingOnly = TRUE)
    if (length(args) < 1) {
      stop('Usage: Rscript fixanddive.R filename\n')
    }

    # Read model
    cat('Reading model',args[1],'...')
    model <- gurobi_read(args[1])
    cat('... done\n')

    # Detect set of non-continous variables
    numvars    <- ncol(model$A)
    intvars    <- which(model$vtype != 'C')
    numintvars <- length(intvars)
    if (numintvars < 1) {
      stop('All model\'s variables are continuous, nothing to do\n')
    }

    # create lb and ub if they do not exists, and set them to default values
    if (!('lb' %in% model)) {
      model$lb <- numeric(numvars)
    }
    if (!('ub' %in% model)) {
      model$ub <- Inf + numeric(numvars)
    }

    # set all variables to continuous
    ovtype                 <- model$vtype
    model$vtype[1:numvars] <- 'C'

    # parameters
    params            <- list()
    params$OutputFlag <- 0

    result <- gurobi(model, params)

    # Perform multiple iterations. In each iteration, identify the first
    # quartile of integer variables that are closest to an integer value
    # in the relaxation, fix them to the nearest integer, and repeat.
    for (iter in 1:1000) {
      # See if status is optimal
      if (result$status != 'OPTIMAL') {
        cat('Model status is', result$status,'\n')
        cat('Cannot keep fixing variables\n')
        break
      }
      # collect fractionality of integer variables
      fractional  <- abs(result$x - floor(result$x+0.5))
      fractional  <- replace(fractional, fractional < 1e-5, 1)
      fractional  <- replace(fractional, ovtype == 'C', 1)
      fractional  <- replace(fractional, ovtype == 'S', 1)
      nfractional <- length(which(fractional<0.51))

      cat('Iteration:', iter, 'Obj:', result$objval,
          'Fractional:', nfractional, '\n')
      if (nfractional == 0) {
        cat('Found feasible solution - objective', result$objval, '\n')
        break
      }

      # order the set of fractional index
      select <- order(fractional, na.last = TRUE, decreasing = FALSE)

      # fix 25% of variables
      nfix <- as.integer(ceiling(nfractional  / 4))
      # cat('Will fix', nfix, 'variables, out of', numvars, '\n')
      if (nfix < 10)
        cat('Fixing ')
      else
        cat('Fixing',nfix,'variables, fractionality threshold:',fractional[select[nfix]],'\n')
      for (k in 1:nfix) {
        j   <- select[k]
        val <- floor(result$x[j] + 0.5)
        model$lb[j] <- val
        model$ub[j] <- val
        if (nfix < 10)
          cat(model$varname[j],'x*=',result$x[j],'to',val,' ')
      }
      if (nfix < 10)
        cat('\n')

      # reoptimize
      result <- gurobi(model, params)
    }

    # Clear space
    rm(model, params, result)

    ' Copyright 2025, Gurobi Optimization, LLC
    '
    ' Implement a simple MIP heuristic.  Relax the model,
    ' sort variables based on fractionality, and fix the 25% of
    ' the fractional variables that are closest to integer variables.
    ' Repeat until either the relaxation is integer feasible or
    ' linearly infeasible.

    Imports System
    Imports System.Collections.Generic
    Imports Gurobi

    Class fixanddive_vb
        ' Comparison class used to sort variable list based on relaxation
        ' fractionality

        Private Class FractionalCompare : Implements IComparer(Of GRBVar)
            Public Function Compare(ByVal v1 As GRBVar, ByVal v2 As GRBVar) As Integer _
                                 Implements IComparer(Of Gurobi.GRBVar).Compare
                Try
                    Dim sol1 As Double = Math.Abs(v1.X)
                    Dim sol2 As Double = Math.Abs(v2.X)
                    Dim frac1 As Double = Math.Abs(sol1 - Math.Floor(sol1 + 0.5))
                    Dim frac2 As Double = Math.Abs(sol2 - Math.Floor(sol2 + 0.5))
                    If frac1 < frac2 Then
                        Return -1
                    ElseIf frac1 > frac2 Then
                        Return 1
                    Else
                        Return 0
                    End If
                Catch e As GRBException
                    Console.WriteLine("Error code: " & e.ErrorCode & ". " & e.Message)
                End Try
                Return 0
            End Function
        End Class

        Shared Sub Main(ByVal args As String())

            If args.Length < 1 Then
                Console.WriteLine("Usage: fixanddive_vb filename")
                Return
            End If

            Try
                ' Read model
                Dim env As New GRBEnv()
                Dim model As New GRBModel(env, args(0))

                ' Collect integer variables and relax them
                Dim intvars As New List(Of GRBVar)()
                For Each v As GRBVar In model.GetVars()
                    If v.VType <> GRB.CONTINUOUS Then
                        intvars.Add(v)
                        v.VType = GRB.CONTINUOUS
                    End If
                Next

                model.Parameters.OutputFlag = 0
                model.Optimize()

                ' Perform multiple iterations. In each iteration, identify the first
                ' quartile of integer variables that are closest to an integer value
                ' in the relaxation, fix them to the nearest integer, and repeat.

                For iter As Integer = 0 To 999

                    ' create a list of fractional variables, sorted in order of
                    ' increasing distance from the relaxation solution to the nearest
                    ' integer value

                    Dim fractional As New List(Of GRBVar)()
                    For Each v As GRBVar In intvars
                        Dim sol As Double = Math.Abs(v.X)
                        If Math.Abs(sol - Math.Floor(sol + 0.5)) > 0.00001 Then
                            fractional.Add(v)
                        End If
                    Next

                    Console.WriteLine("Iteration " & iter & ", obj " & _
                                      model.ObjVal & ", fractional " & fractional.Count)

                    If fractional.Count = 0 Then
                        Console.WriteLine("Found feasible solution - objective " & _
                                          model.ObjVal)
                        Exit For
                    End If

                    ' Fix the first quartile to the nearest integer value

                    fractional.Sort(New FractionalCompare())
                    Dim nfix As Integer = Math.Max(fractional.Count / 4, 1)
                    For i As Integer = 0 To nfix - 1
                        Dim v As GRBVar = fractional(i)
                        Dim fixval As Double = Math.Floor(v.X + 0.5)
                        v.LB = fixval
                        v.UB = fixval
                        Console.WriteLine("  Fix " & v.VarName & " to " & fixval & _
                                          " ( rel " & v.X & " )")
                    Next

                    model.Optimize()

                    ' Check optimization result

                    If model.Status <> GRB.Status.OPTIMAL Then
                        Console.WriteLine("Relaxation is infeasible")
                        Exit For
                    End If
                Next

                ' 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