3.8.1 A small MIP model (mip1-c)

Run LPL Code  ,  PDF Document

Problem

The problem is the following small linear integer model :

max    x + y + 2z
s.t    x + 2y + 3z ≤ 4
       x + y ≥ 1
       x, y, z ∈ [0,1]

The optimal solution is (x,y,z) = (1, 0, 1). The example is from Gurobi Examples.

Further Comments

LPL calls Gurobi’s library to solve the model. Internally, it is basically the same code as the C code below, but all those implementation details are hidden from the modeler. The C code first declares the data needed. Then the model is initialized, license is checked, some parameters are set using the library functions GRBemptyenv, GRBsetstrparam, GRBstartenv, GRBnewmodel. After the initialization, variables and constraints are added with GRBaddvars and GRBaddconstr, the optimizer is called (GRBoptimize) and finally various output functions extract the solution.

That is basically the same as LPL does when calling the Gurobi solver.

LPL code (run mip1-c)

model mip1c "A small MIP model"; 
  binary variable x; y; z; 
  maximize O:    x +   y + 2*z; 
  constraint C1: x + 2*y + 3*z <= 4; 
             C2: x +   y       >= 1; 
  Writep(O,x,y,z); 
end

C code for gurobi (download mip1-c.c)

// Copyright 2022, Gurobi Optimization, LLC 
#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[3]; 
  char      vtype[3]; 
  int       optimstatus; 
  double    objval; 
 
  error = GRBemptyenv(&env); if (error) goto QUIT; 
  error = GRBsetstrparam(env, "LogFile", "mip1.log"); if (error) goto QUIT; 
  error = GRBstartenv(env); if (error) goto QUIT; 
  error = GRBnewmodel(env, &model, "mip1", 0, NULL, NULL, NULL, NULL, NULL); if (error) goto QUIT; 
 
  // Add variables 
  obj[0] = 1; obj[1] = 1; obj[2] = 2; 
  vtype[0] = GRB_BINARY; vtype[1] = GRB_BINARY; vtype[2] = GRB_BINARY; 
  error = GRBaddvars(model, 3, 0, NULL, NULL, NULL, obj, NULL, NULL, vtype, NULL); 
  if (error) goto QUIT; 
 
  // Change objective sense to maximization 
  error = GRBsetintattr(model, GRB_INT_ATTR_MODELSENSE, GRB_MAXIMIZE); 
  if (error) goto QUIT;

C code for gurobi, continuing ...

  // First constraint: x + 2 y + 3 z <= 4 
  ind[0] = 0; ind[1] = 1; ind[2] = 2; 
  val[0] = 1; val[1] = 2; val[2] = 3; 
 
  error = GRBaddconstr(model, 3, ind, val, GRB_LESS_EQUAL, 4.0, "c0"); 
  if (error) goto QUIT; 
 
  // Second constraint: x + y >= 1 
  ind[0] = 0; ind[1] = 1; 
  val[0] = 1; val[1] = 1; 
 
  error = GRBaddconstr(model, 2, ind, val, GRB_GREATER_EQUAL, 1.0, "c1"); 
  if (error) goto QUIT; 
 
  // Optimize model 
  error = GRBoptimize(model); 
  if (error) goto QUIT; 
 
  // Write model to 'mip1.lp' 
  error = GRBwrite(model, "mip1.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=%.0f, y=%.0f, z=%.0f' 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: 
  if (error) { 
    printf("ERROR: %s' n", GRBgeterrormsg(env)); exit(1); 
  } 
  // Free model 
  GRBfreemodel(model); 
  // Free environment 
  GRBfreeenv(env); 
  return 0; 
}