Initializing help system before first use

Production planning under demand uncertainty


Type: Production planning
Rating: 3 (intermediate)
Description: Planning the production of several types of drinking glasses for the next N weeks subject to uncertain demand (formulated via scenarios) or uncertain resource capacity limits (polyhedral uncertainty).
File(s): c2glass_robust.mos
Data file(s): c2glass_scen.dat


c2glass_robust.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file c2glass_robust.mos
   ```````````````````````
   Planning the production of glasses
   - Robust against demand scenarios or workers' absence -
   
   Based on c2_glass.mos (Mar 2002)
   
   (c) 2014 Fair Isaac Corporation
       author: S. Heipcke, Apr. 2014
*******************************************************!)

model "C-2 Glass production (scenarios)"
 uses "mmrobust"
 parameters
   DATAFILE="c2glass_scen.dat"
   IF_SCEN = true  !false
   IF_WORK = false !true
 end-parameters  

 declarations   
  WEEKS: range                           ! Planning period
  PRODS: range                           ! Set of products
  SCEN: range                            ! Demand scenarios

  CAPW,CAPM: integer                     ! Capacity of workers and machines
  CAPS: integer                          ! Storage capacity
  SCENDEM: array(SCEN,PRODS,WEEKS) of integer  ! Demand per product & week
  CPROD: array(PRODS) of integer         ! Production cost per product
  CSTOCK: array(PRODS) of integer        ! Storage cost per product
  ISTOCK: array(PRODS) of integer        ! Initial stock levels
  FSTOCK: array(PRODS) of integer        ! Min. final stock levels
  TIMEW,TIMEM: array(PRODS) of integer   ! Worker and machine time per unit
  SPACE: array(PRODS) of integer         ! Storage space required by products
  ABSENCE: dynamic array(WEEKS) of real  ! Max. absence (hours)

  produce: array(PRODS,WEEKS) of mpvar   ! Production of products per week
  store: array(PRODS,WEEKS) of mpvar     ! Amount stored at end of week 
  absent: dynamic array(WEEKS) of uncertain      ! Absence of personnel
  demand: dynamic array(PRODS,WEEKS) of uncertain  ! Uncertain demand
  SCENDATA: array(SCEN,set of uncertain) of real  ! Aux. data structure
 end-declarations

 initializations from DATAFILE
  CAPW CAPM CAPS SCENDEM CSTOCK CPROD
  ISTOCK FSTOCK TIMEW TIMEM SPACE ABSENCE
 end-initializations

! Objective: sum of production and storage costs
 Cost:= 
  sum(p in PRODS, t in WEEKS) (CPROD(p)*produce(p,t) + CSTOCK(p)*store(p,t))

 if IF_SCEN then
 ! Demand scenarios
   forall(p in PRODS, t in WEEKS | sum(s in SCEN) SCENDEM(s,p,t)>0) 
     create(demand(p,t))
   forall(s in SCEN, p in PRODS, t in WEEKS | SCENDEM(s,p,t)>0) 
     SCENDATA(s, demand(p,t)):= SCENDEM(s,p,t)
   scenario(SCENDATA)

 ! Stock balances
   forall(p in PRODS, t in WEEKS) do
     store(p,t) <= if(t>1, store(p,t-1), ISTOCK(p)) + produce(p,t) - demand(p,t)
     store(p,t) >= if(t>1, store(p,t-1), ISTOCK(p)) + produce(p,t) - 
       max(s in SCEN) SCENDEM(s,p,t)
   end-do

   setparam("ROBUST_UNCERTAIN_OVERLAP", true)
 else
   forall(p in PRODS, t in WEEKS)
     store(p,t) =
       if(t>1, store(p,t-1), ISTOCK(p)) + produce(p,t) - SCENDEM(1,p,t)
 end-if

! Final stock levels
 forall(p in PRODS) store(p,WEEKS.last) >= FSTOCK(p)

 if IF_WORK then
   ! Limit on total absence (uncertainty set)
   forall(t in WEEKS) create(absent(t))
   sum(t in WEEKS) absent(t) <= 0.05*CAPW*WEEKS.size
   forall(t in WEEKS) absent(t) <= ABSENCE(t)
   forall(t in WEEKS) absent(t) >= 0
   
   setparam("ROBUST_UNCERTAIN_OVERLAP", true)
 end-if  

! Capacity constraints 
 forall(t in WEEKS) do
  if IF_WORK then
    sum(p in PRODS) TIMEW(p)*produce(p,t) <= CAPW -absent(t) ! Workers
  else
    sum(p in PRODS) TIMEW(p)*produce(p,t) <= CAPW/1.1        ! Workers
  end-if 
  sum(p in PRODS) TIMEM(p)*produce(p,t) <= CAPM              ! Machines
  sum(p in PRODS) SPACE(p)*store(p,t)   <= CAPS              ! Storage
 end-do


! Solve the problem
 minimize(Cost)
 
! Solution printing
 if getprobstat<>XPRS_OPT then
   writeln("No solution found."); exit(1)
 end-if  
 writeln("Total cost: ",getobjval)
 writeln("Production plan:")
 write("     Week")
 forall(t in WEEKS) write(strfmt(t,7))
 writeln
 forall(p in PRODS) do
  write(p,": Prod. ")
  forall(t in WEEKS) write(strfmt(getsol(produce(p,t)),7,1))
  writeln
  write("   Store  ")
  forall(t in WEEKS) write(" (", if( store(p,t).sol>0,  
                           strfmt(getsol(store(p,t)),4,1), "  - "),  ")")
  writeln
 end-do

 writeln("\nCapacities used:")
 writeln("Week",strfmt("Workers",8),strfmt("Machines",9),strfmt("Space",7))
 forall(t in WEEKS) 
  writeln(strfmt(t,2),
   strfmt(ceil(getsol(sum(p in PRODS) TIMEW(p)*produce(p,t))),8),
   strfmt(getsol(sum(p in PRODS) TIMEM(p)*produce(p,t)),10,2),
   strfmt(getsol(sum(p in PRODS) SPACE(p)*store(p,t)),9,2) ) 
 
end-model

© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.