MicroCity

< 4.4 Discrete Event Simulation Table of Contents

4.5 Mixed Integer Programming

Linear programming and mixed integer programming are important tools in operations research, and functions and some examples for solving these models are provided here. Note that a call mip:func(args) is syntactic sugar for math.func(mip, args).

Functions

For the convenience of explanation later, first look at a typical Linear Programming (LP) model:

       min     d1*x1 +  d2*x2 + ... +  dn*xn
subject to    a11*x1 + a12*x2 + ... + a1n*xn >= b1
              a21*x1 + a22*x2 + ... + a2n*xn >= b2
                   ........................
              am1*x1 + am2*x2 + ... + amn*xn >= bn

This model has n columns of variables and m + 1 rows of lower bound constraints (the objective function is also a special inequality). There are also m dual variables. Mixed Integer Programming (MIP) problem is an LP problem in which some variables are additionally required to be integer. In order to concisely construct mip models and solve them, we designed the following six functions. Note that a call mip:func(args) is syntactic sugar for math.func(mip, args).

math.newmip ([fin])

Create a new mip model or read a model in CPLEX LP format from a file fin and return it. By default, every column variable is greater than or equal to 0.

mip:addrow (coltab|colname, bndtype [, b [, rowname]])

Add a row to the model mip.

mip:delrow (rownum|rowname)

Delete a row frome the mip model.

mip:addcol (rowtab, bndtype, d [, colname])

Add a column to the model mip.

mip:delcol (colnum|colname)

Delete a column frome the mip model.

mip:solve ([fout])

Solve the mip model (save the model in CPLEX LP format to a file fout).

Example Models

Here two simple models are demonstrated, first is a Mixed Integer Programming model with two variables and two constraints:

       max     143x1 + 60x2
subject to     110x1 + 30x2 <= 4000
                  x1 +   x2 <= 75
                  x1        ∈ {0, 1, 2, ...}
                         x2 ∈ {0, 1}

Translate the mathematical model into code:

local mip = math.newmip()                   --create a integer programming

mip:addrow({x1 = 143, x2 = 60}, 'max')      --set the objective function
mip:addrow({x1 = 110, x2 = 30}, '<=', 4000) --add the first constraint
mip:addrow({x1 = 1,   x2 = 1},  '<=', 75)   --add the second constraint
mip:addrow('x1', 'int')                     --set x1 a integer bound
mip:addrow('x2', 'bin')                     --set x2 a binary bound
mip:solve()                                 --solve the model               

print(mip.obj, ' ', mip.x1, ' ', mip.x2)    --print objective and variables values

Let’s show a slightly more complex example, which is a linear program with abbreviations for the objective function and constraints:

There are 100 variables and 100 constraints in this model, which cannot be added one by one manually. They need to be processed through a loop:

local lp = math.newmip()         --create a linear programming 
local c = {}                     --create a coefficient array
for i = 1, 100 do                --traverse the array
     c[i] = i                    --set the coefficient
end
lp:addrow(c, "min")              --set the objective function

for i = 1, 100 do                --traverse the 100 constraints
     local w = {}                --create an array of constraint coefficients
     for j = 1, 100 do           --traverse the 100 constraint coefficients
         if i==j then            --if the row number is equal to the column number
             w[j] = 1            --set the coefficient to 1
         else
             w[j] = 0            --otherwise set the coefficient to 0
         end
     end
     lp:addrow(w, ">=", 2)       --add constraints to the model
end
lp:solve()                       --solve the model

print(lp['obj'])                 --print the objective value
< 4.4 Discrete Event Simulation Table of Contents