2.7.1 A Tiny Planning Model (tiny-initial)

Run LPL Code  ,  PDF Document


Pochet/Wolsey [11] introduce the production planning models by a tiny example: A manufacturer plans to produce a high-tech bicycle. In each month at most one batch is produced in order to satisfy the demand. Sales forecast for the product is given. What should the batch sizes be in each month in order to satisfy the demand and to minimize costs? More information is given in model tiny.

Modeling Steps

We introduce a set t T = {1,, 8} to specify the planning horizon. Let q = 5000 be the set-up cost of a batch, p = 100 the production cost of a unit, s0 = 200 the initial stock, and h = 5 the storage cost of a unit in stock per month. The demand in each months is given as dt. We want to know the quantities xt 0 of bicycles produced in each month. Furthermore, we want to know the quantity in stock at the end of each month (st 0). The quantity in stock at the end should be zero, hence s8 = 0. Finally, a binary variable yt is needed to specify whether a batch must be opened (= 1) in month t or not (= 0). The model then is as follows:

     ∑         ∑        ∑
min      pxt +     hst +    qyt
       t        t         t
s.t.  st-1 + xt = dt + st          forall t ∈ T
     x  ≤ M  y                    forall t ∈ T
       t      t
     s0 = s0, s|T| = 0
     xt ≥ 0, st ≥ 0, yt ∈ {0, 1} Sucht ∈  T

Costs are to be minimized. They are composed by production costs the storage costs, and the set-up costs. The first constraint defines the balance from period to period: stock at the beginning of t plus production equal demand plus stock at the end of t. The second constraint defines the connection beween production and batch opening: if no batch is opened (yt = 0), then no bike is produced (xt = 0).

LPL code (run tiny-initial)

model tiny "A Tiny Planning Model"; 
  set t,k     "Range of time"; 
  parameter q "Setup cost"; 
    p         "Price per unit"; 
    s0        "Inital Inventory"; 
    h         "Unit storage cost"; 
    d{t}      "Demand"; 
  variable x{t} "Production"; 
           s{t} "Storage"; 
  binary variable y{t} "=1, batch opened in t"; 
    dem_sat{t}: if(t=1,s0,s[t-1]) + x[t] = d[t] + s[t]; 
    vub{t}: x[t] <= (sum{k} d[k])*y[t]; 
    endStock: s[#t]=0; 
  minimize cost: 
    sum{t} (p*x[t]+q*y[t]+if(t<#t,h,h/2)*s[t]); 
  model data; 
    q:=5000;  p:=100;  s0:=200;  h:=5; 
    d{t} := /Jan 400 Feb 400 Mar 800 Apr 800 
             May 1200 Jun 1200 Jul 1200 Aug 1200/; 
  model output; 
    Write(' %7s ' nDemand %7d ' nProduc %7d'  
' nInvent %7d ' n' n P cost %7d ' nI cost %7d'  
' nSet-up %7d ' n' n Total costs: %7d', 
      {t}t, {t}d, {t}x, {t}s, {t}p*x, {t}h*s, {t}q*y,cost); 

MOSEL code (download tiny-initial.mos)

model tiny                ! Start a new model 
uses "mmxprs","mmsystem"  ! Load the optimizer library 
options noimplicit 
 EPS=1e-6                 ! Zero tolerance 
 T=8                      ! Number of time periods 
 RT=1..T                  ! Range of time 
 DEMAND: array(RT) of integer ! Demand per period 
 SETUPCOST: integer   ! Setup cost per period 
 PRODCOST: integer    ! Production cost per period 
 INVCOST: integer     ! Production cost per period 
 STOCKINI: integer    ! Production cost per period 
 D: array(RT,RT) of integer  ! Demand per period 
 s: array(RT) of mpvar       ! Inventory in period t 
 x: array(RT) of mpvar       ! Production in period t 
 y: array(RT) of mpvar       ! Setup in period t 
 balance: array(RT) of linctr 
 production: array(RT) of linctr 
 mincost : linctr 
 vi1: array(RT) of linctr 
 DEMAND:= [400,400,800,800,1200,1200,1200,1200]

...continuing MOSEL code ...

 SETUPCOST:= 5000 
 PRODCOST:=  100 
 INVCOST:=   5 
 STOCKINI:=  200 
 forall(r in RT, t in RT) do 
   if (r <= t) then 
     D(r,t):= sum(k in r..t) DEMAND(k) 
     D(r,t) := 0 
! Objective: minimize total cost 
   sum(t in RT ) (if(t<T,INVCOST,INVCOST/2))*s(t) + 
   sum(t in RT)  (SETUPCOST*y(t) + PRODCOST*x(t)) 
 forall(t in RT) production(t):= x(t) <= D(t,T)*y(t) 
 forall(t in RT) balance(t):= 
   if (t=1,STOCKINI,s(t-1))+x(t) = DEMAND(t) + s(t) 
 forall(t in RT) y(t) is_binary ! Vars setup are 0/1 
 setparam("XPRS_VERBOSE", 1)    ! 
 setparam("XPRS_MIPLOG", 3)     ! 
 setparam("XPRS_PRESOLVE", 1)   ! Disable PRESOLVE 
 setparam("XPRS_CUTSTRATEGY", 0) ! Disable autom. cuts 
 !minimize(XPRS_LIN, mincost) 
 forall(t in RT) 
  writeln("Period ", t,": prod ", getsol(x(t))," (demand: ", DEMAND(t), 
          ", unit cost: ", PRODCOST, "), setup ", getsol(y(t)), 
          " (cost: ", SETUPCOST, ", stock: ", getsol(s(t)), ")")