Initializing help system before first use

C. Planning problems


Description:

Problem name and type, features Difficulty Related examples
C‑1 Planning the production of bicycles: Production planning (single product) ***
modeling inventory balance; inline if, forall-do
C‑2 Production of drinking glasses: Multi-item production planning ** prodplan_graph.mos
modeling stock balance constraints; inline if, index value 0
C‑3 Material requirement planning: Material requirement planning (MRP) **
working with index (sub)sets, dynamic initialization, automatic finalization, as
C‑4 Planning the production of electronic components: Multi-item production planning ** c2glass.mos
modeling stock balance constraints; inline if
C‑5 Planning the production of fiberglass: Production planning with time-dependent production cost *** transship_graph.mos
representation of multi-period production as flow; encoding of arcs, exists, create, isodd, getlast, inline if
C‑6 Assignment of production batches to machines: Generalized assignment problem * assignment_graph.mos


File(s): c1bike.mos (Mar. 2002), c2glass.mos (Mar. 2002), c3toy.mos (Mar. 2002), c4compo.mos (Mar. 2002), c5fiber.mos (Mar. 2002), c6assign.mos (Mar. 2002)
Data file(s): c1bike.dat, c2glass.dat, c3toy.dat, c4compo.dat, c5fiber.dat, c6assign.dat

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

   file c1bike.mos
   ```````````````
   Planning the production of bicycles

   A sales forecast shows the predicted bicycle demand for the
   upcoming year. There is a set production capacity per month
   but it can be increased with overtime (with additional costs).
   The company can store excess bikes at a small cost with no
   limit to quantity. How many bikes need to be produced and
   stored in the next year to meet the forecasted demand while
   minimizing total (production, overtime, storage) cost?

   This implementation using the inline 'if' function to condense
   the balance constraints since this varies for t=1 and t>1.
   Note that there is no slack built into the demand forecast so
   bike storage will be as low as possible to reduce total cost.
   This may not be practical if there is an unpredicted spike in
   demand.

   (c) 2008-2022 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. Mar. 2022
*******************************************************!)

model "C-1 Bicycle production"
 uses "mmxprs"

 declarations   
  TIMES = 1..12                  ! Range of time periods

  DEM: array(TIMES) of integer   ! Demand per months
  CNORM,COVER: integer           ! Prod. cost in normal / overtime hours
  CSTOCK: integer                ! Storage cost per bicycle
  CAP: integer                   ! Monthly capacity in normal working hours
  ISTOCK: integer                ! Initial stock

  pnorm:array(TIMES) of mpvar    ! No. of bicycles produced in normal hours
  pover:array(TIMES) of mpvar    ! No. of bicycles produced in overtime hours
  store:array(TIMES) of mpvar    ! No. of bicycles stored per month 
 end-declarations

 initializations from 'c1bike.dat'
  DEM CNORM COVER CSTOCK CAP ISTOCK 
 end-initializations

! Objective: minimize production cost
 Cost:= sum(t in TIMES) (CNORM*pnorm(t) + COVER*pover(t) + CSTOCK*store(t))

! Satisfy the demand for every period
 forall(t in TIMES) 
  pnorm(t) + pover(t) + if(t>1, store(t-1), ISTOCK) = DEM(t) + store(t)

! Capacity limits on normal and overtime working hours per month
 forall(t in TIMES) do
  pnorm(t) <= CAP
  pover(t) <= 0.5*CAP
 end-do

! Solve the problem
 minimize(Cost)
 
! Solution printing
 declarations
  MONTHS: array(TIMES) of string  ! Names of months
 end-declarations 

 initializations from 'c1bike.dat'
  MONTHS 
 end-initializations
 
 writeln("Total cost: ", getobjval)
 write("       ")
 forall(t in TIMES) write(strfmt(MONTHS(t),4))
 setparam("realfmt", "%4g")    ! Reserve 4 char.s for display of real numbers
 write("\nDemand ")
 forall(t in TIMES) write(DEM(t)/1000)
 write("\nNormal ")
 forall(t in TIMES) write(getsol(pnorm(t))/1000)
 write("\nAdd.   ")
 forall(t in TIMES) write(getsol(pover(t))/1000)
 write("\nStore  ")
 forall(t in TIMES) write(getsol(store(t))/1000)
 writeln

end-model

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

   file c2glass.mos
   ````````````````
   Planning the production of glasses
   
   A French company produces 6 types of drinking glasses.
   Each product has varying production cost, storage cost, 
   initial stock, and storage space requirements. The time it
   take a work and machine to create each batch of glasses 
   also varies. How much of each type of glasses should be 
   produced in each period so that the total (production and 
   storage) cost be minimized?
   
   A balance constraint is necessary to define the glasses 
   stored from one period to the next. Note that the production 
   variable cannot be named 'prod' and the set of products 
   cannot be named 'PROD' as 'prod' is a reserved word since 
   it is a keyword of Mosel.
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002
*******************************************************!)

model "C-2 Glass production"
 uses "mmxprs", "mmsystem"

 declarations   
  NT = 12                              ! Number of weeks in planning period
  WEEKS = 1..NT 
  PRODS = 1.. 6                        ! Set of products

  CAPW,CAPM: integer                   ! Capacity of workers and machines
  CAPS: integer                        ! Storage capacity
  DEM: array(PRODS,WEEKS) of integer   ! Demand per product and per 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
  
  produce: array(PRODS,WEEKS) of mpvar ! Production of products per week
  store: array(PRODS,WEEKS) of mpvar   ! Amount stored at end of week 
 end-declarations

 initializations from 'c2glass.dat'
  CAPW CAPM CAPS DEM CSTOCK CPROD ISTOCK FSTOCK TIMEW TIMEM SPACE
 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))

! Stock balances
 forall(p in PRODS, t in WEEKS)
  store(p,t) = if(t>1, store(p,t-1), ISTOCK(p)) + produce(p,t) - DEM(p,t)

! Final stock levels
 forall(p in PRODS) store(p,NT) >= FSTOCK(p)

! Capacity constraints 
 forall(t in WEEKS) do
  sum(p in PRODS) TIMEW(p)*produce(p,t) <= CAPW     ! Workers
  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
 writeln("Total cost: ",getobjval)
 writeln("Production plan:")
 write("     Week")
 forall(t in WEEKS) write(textfmt(t,7))
 writeln
 forall(p in PRODS) do
  write(p,": Prod. ")
  forall(t in WEEKS) write(textfmt(getsol(produce(p,t)),7))
  writeln
  write("   Store ")
  forall(t in WEEKS) write(textfmt("("+getsol(store(p,t))+")",7))
  writeln
 end-do

 writeln("\nCapacities used:")
 writeln(formattext("Week%8s%9s%7s","Workers","Machines","Space"))
 forall(t in WEEKS) 
  writeln(formattext("%2d%8g%10.2f%9.2f", t,
   getsol(sum(p in PRODS) TIMEW(p)*produce(p,t)),
   getsol(sum(p in PRODS) TIMEM(p)*produce(p,t)),
   getsol(sum(p in PRODS) SPACE(p)*store(p,t))) ) 
	   
end-model

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

   file c3toy.mos
   ``````````````
   Planning the production of toy lorrys

   A company produces two types of large toy lorry (trucks).
   Each toy has 13 components. A subset of items can be assembled
   by the company or subcontracted. Given the demand is the
   same for both toys, how much should the company buy or
   subcontract to meet demand and minimize cost?

   Index sets are not fixed and are instead initialized from
   the data file when reading the array data. The index sets of dense
   arrays are automatically finalized by Mosel. As a consequence,
   the arrays of decision variables 'produce' and 'buy' that are 
   declared in the same declarations block and are first accessed after 
   data has been initialized (when their index sets are known and
   have been finalized) will be created automatically without any
   need for an explicit call of the function 'create'.
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, re. Mar. 2022
*******************************************************!)

model "C-3 Toy production"
 uses "mmxprs", "mmsystem"

 declarations   
  ITEMS: set of string                 ! Set of all products
  FINAL: set of string                 ! Set of final products
  ASMBL: set of string                 ! Set of assembled products
  PREPROD: set of string               ! Set of preproducts

  CAP: array(ASMBL) of integer         ! Capacity of assembly lines
  DEM: array(FINAL) of integer         ! Demand of lorrys
  CPROD: array(ASMBL) of real          ! Assembly costs
  CBUY: array(ITEMS) of real           ! Purchase costs
  REQ: array(ASMBL,PREPROD) of integer ! Items req. for assembling a product

  produce: array(ASMBL) of mpvar       ! Quantity of items produced
  buy: array(PREPROD) of mpvar         ! Quantity of items bought 
 end-declarations

 initializations from 'c3toy.dat'
  DEM CBUY REQ
  [CPROD, CAP] as 'ASSEMBLY'
 end-initializations

! Objective: total costs
 Cost:= sum(p in PREPROD) CBUY(p)*buy(p) + 
         sum(p in ASMBL) CPROD(p)*produce(p)

! Satisfy demands
 forall(p in FINAL) produce(p) >= DEM(p)

! Assembly balance
 forall(p in PREPROD) buy(p) + if(p in ASMBL, produce(p), 0) >= 
                       sum(q in ASMBL) REQ(q,p)*produce(q)

! Limits on assembly capacity
 forall(p in ASMBL) produce(p) <= CAP(p)

 forall(p in PREPROD) buy(p) is_integer
 forall(p in ASMBL) produce(p) is_integer

! Solve the problem
 minimize(Cost)
 
! Solution printing
 writeln("Total cost: ",getobjval)
 writeln("Buy:")
 forall(p in PREPROD)
  writeln(formattext("  %-18s: %5g", p, getsol(buy(p)))) 
 writeln("Produce:")
 forall(p in ASMBL)
  writeln(formattext("  %-18s: %5g", p, getsol(produce(p)))) 

end-model

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

   file c4compo.mos
   ````````````````
   Planning the production of electronic components
   
   A company produces cards with microchips and electronic
   badges. They also produce the components for these. The 
   company would like to meet the forecasted demand while 
   minimizing the cost associated to production, storage, 
   and product changes.
   
   This is a simple planning problem with an addition of 
   one new cost type (product changes). A balance constraint 
   is necessary to define the products stored from one period
   to the next. 

   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002
*******************************************************!)

model "C-4 Electronic components"
 uses "mmxprs"

 declarations   
  NT = 6                                 ! Number of time periods (months)
  MONTHS = 1..NT
  PRODS = 1..4                           ! Set of components

  DEM: array(PRODS,MONTHS) of integer    ! Demand of components per month
  CPROD: array(PRODS) of integer         ! Production costs
  CSTOCK: array(PRODS) of real           ! Storage costs
  CADD,CRED: real                        ! Cost of additional/reduced prod.
  ISTOCK,FSTOCK: array(PRODS) of integer ! Initial and final stock levels

  produce: array(PRODS,MONTHS) of mpvar  ! Quantities produced per month
  store: array(PRODS,MONTHS) of mpvar    ! Stock levels at end of every month
  reduce: array(MONTHS) of mpvar         ! Reduction of production per month 
  add: array(MONTHS) of mpvar            ! Increase of production per month 
 end-declarations

 initializations from 'c4compo.dat'
  DEM CPROD CSTOCK CADD CRED ISTOCK FSTOCK
 end-initializations

! Objective: total cost of production, storage, and change of prod. level
 Cost:= sum(p in PRODS, t in MONTHS) (CPROD(p)*produce(p,t) + 
                                      CSTOCK(p)*store(p,t)) +
        sum(t in 2..NT) (CRED*reduce(t) + CADD*add(t))

! Stock balance constraints (satisfy demands)
 forall(p in PRODS, t in MONTHS)
  store(p,t) = if(t>1, store(p,t-1), ISTOCK(p)) + produce(p,t) - DEM(p,t)

! Changes to the level of production 
 forall(t in 2..NT) 
  sum(p in PRODS) (produce(p,t) - produce(p,t-1)) = add(t) - reduce(t)

! Guarantee final stock levels
forall(p in PRODS) store(p,NT) >= FSTOCK(p)

! Solve the problem
 minimize(Cost)
 
! Solution printing
 declarations
  PNAME: array(PRODS) of string          ! Product names
 end-declarations 

 initializations from 'c4compo.dat'
  PNAME 
 end-initializations

 writeln("Total cost: ",getobjval)
 write(strfmt("Month",13))
 forall(t in MONTHS) write(strfmt(t,5))
 forall(p in PRODS) do
  write("\n", PNAME(p), ": Prod. ")
  forall(t in MONTHS) write(strfmt(getsol(produce(p,t)),5))
  write("\n", strfmt("Store ",14))
  forall(t in MONTHS) write(strfmt("("+store(p,t).sol+")",5))
 end-do
 write("\nTotal         ")
 forall(t in MONTHS) write(strfmt(sum(p in PRODS) produce(p,t).sol,5))
 writeln

end-model

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

   file c5fiber.mos
   ````````````````
   Planning the production of fiberglass
 
   The next 6 weeks of fiberglass production needs to be
   planned. Capacity is limited and varies by week. Production
   and storage costs also change over time. Determine
   the plan that minimizes total cost of production and
   storage while meeting demand for the time period.

   This problem introduces a transshipment flow formulation.
   The demand and capacity data are represented as node weights
   and are combined into a single array 'WEIGHT'. 'ARC' defines
   the cost of flow between nodes. Note that since the array of
   variables 'flow' is dynamic, it must be created after the data is 
   read and only for node combinations where 'ARC' exists. Two new
   functions are introduced here: 'isodd' determines if an integer
   value is odd or even and 'getlast' returns the last entry of a
   range or a list.  

   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. Nov. 2017
*******************************************************!)

model "C-5 Fiberglass"
 uses "mmxprs"

 declarations   
  NODES: range                           ! Production and demand nodes
                                         ! odd numbers: production capacities
                                         ! even numbers: demands

  ARC: dynamic array(NODES,NODES) of real   ! Cost of flow on arcs
  WEIGHT: array(NODES) of integer           ! Node weights (capacities/demand)

  flow: dynamic array(NODES,NODES) of mpvar ! Flow on arcs   
 end-declarations

 initializations from 'c5fiber.dat'
  ARC WEIGHT
 end-initializations

 forall(m,n in NODES | exists(ARC(m,n))) create(flow(m,n))

! Objective: total cost of production and storage
 Cost:= sum(m,n in NODES | exists(ARC(m,n))) ARC(m,n)*flow(m,n)

! Satisfy demands (flow balance constraints)
 forall(n in NODES | isodd(n)=FALSE)
  if(n>2, flow(n-2,n), 0) + flow(n-1,n) = 
   if(n<getlast(NODES), flow(n,n+2), 0) + WEIGHT(n)

! Production capacities
 forall(n in NODES | isodd(n)) flow(n,n+1) <= WEIGHT(n)

! Solve the problem
 minimize(Cost)
 
! Solution printing
 writeln("Total cost: ",getobjval)
 write("Week")
 forall(t in 1..integer(getlast(NODES)/2)) write(strfmt(t,5))
 write("\nProd.")
 forall(n in NODES | isodd(n)) 
  write(strfmt(getsol(sum(m in NODES) flow(n,m)),5))
 write("\nStock")
 forall(n in NODES | not(isodd(n))) 
  write(strfmt(getsol(sum(m in NODES) flow(n,m)),5))
 writeln

end-model

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

   file c6assign.mos
   `````````````````
   Machine assignment for production batches
   
   10 batches must be produced in the upcoming period. There
   are 5 machines that can produce any given batch. However,
   processing time and cost depends on machine assignment.
   Each machine has a max production capacity. Determine the
   batch to machine assignment that minimizes the total cost
   of production.
   
   This is a generalized assignment problem and is a very
   compact mathematical model. Each batch must be assigned
   to only one machine and each machine must produce no more
   than its specified capacity. 

   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002
*******************************************************!)

model "C-6 Machine assignment"
 uses "mmxprs"

 declarations   
  MACH = 1..5                        ! Set of machines
  PRODS = 1..10                      ! Set of production batches

  CAP: array(MACH) of integer        ! Machine capacities
  DUR: array(MACH,PRODS) of integer  ! Production durations
  COST: array(MACH,PRODS) of integer ! Production costs

  use: array(MACH,PRODS) of mpvar    ! 1 if machine assigned to batch, 
                                     ! 0 otherwise
 end-declarations

 initializations from 'c6assign.dat'
  DUR CAP COST
 end-initializations

! Objective: total production cost
 Cost:= sum(m in MACH, p in PRODS) COST(m,p)*use(m,p)

! Assign a single machine to every batch
 forall(p in PRODS) sum(m in MACH) use(m,p) = 1

! Limits on machine capacities
 forall(m in MACH) sum(p in PRODS) DUR(m,p)*use(m,p) <= CAP(m)

 forall(m in MACH, p in PRODS) use(m,p) is_binary

! Solve the problem
 minimize(Cost)
 
! Solution printing
 writeln("Total cost: ",getobjval)
 forall(m in MACH) do
  write("Machine ", m, ": ")
  forall(p in PRODS) 
   if (getsol(use(m,p))=1) then
    write(p, " ")
   end-if
  writeln(" (total duration: ", getsol(sum(p in PRODS) DUR(m,p)*use(m,p)), ")")
 end-do

end-model

© 2001-2024 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.