FICO Xpress Optimization Examples Repository
 FICO Optimization Community FICO Xpress Optimization Home

Production planning under demand uncertainty

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).

Further explanation of this example: Whitepaper 'Robust Optimization with Xpress', Section 3 Production planning under demand uncertainty

 robc2glass.zip [download all files]

Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
 c2glass_robust.mos [download]

Data Files
 c2glass_scen.dat [download]

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

`