FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

Timetabling and personnel planning

Description
Problem name and type, featuresDifficultyRelated examples
I‑1 Assigning personnel to machines: Assignment problem **** assignment_graph.mos, c6assign.mos
formulation of maximin objective; heuristic solution + 2 different problems (incremental definition) solved, working with sets, while-do, forall-do
I‑2 Scheduling nurses ***
2 problems, using mod to formulate cyclic schedules; forall-do, set of integer, getact
I‑3 Establishing a college timetable *** timetable_graph.mos
many specific constraints, tricky (pseudo) objective function
I‑4 Exam schedule **
symmetry breaking, no objective
I‑5 Production planning with personnel assignment ***
2 problems, defined incrementally with partial re-definition of constraints (named constraints), exists, create, dynamic array
I‑6 Planning the personnel at a construction site ** persplan_graph.mos
formulation of balance constraints using inline if


Further explanation of this example: 'Applications of optimization with Xpress-MP', Chapter 14: Timetabling and personnel planning

mosel_app_9.zip[download all files]

Source Files

Data Files





i5pplan.mos

(!******************************************************
   Mosel Example Problems
   ======================

   file i5pplan.mos
   ````````````````
   Production planning with personnel assignment
  
   A company must plan the production for a set of products
   on different production lines. Unitary processing times 
   for each product at each line, production line capacities,
   and profit per product are provided. It is possible to 
   transfer working hours (up to a given maximum allowed) 
   between some production lines. What quantity of each 
   product should be produced to maximize total profit?
   
   The hours transferred between production lines are modeled as
   a decision variable which is defined as a dynamic array. Only
   when the data that indicates the allowable transfers is known 
   the transfer variables are created.

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

model "I-5 Production planning with personnel"
 uses "mmxprs"

 forward procedure printsol

 declarations
  PRODS = 1..4                        ! Set of products
  LINES = 1..5                        ! Set of production lines
  
  PROFIT: array(PRODS) of integer     ! Profit per product
  DUR: array(PRODS,LINES) of real     ! Duration of production per line
  CAP: array(LINES) of integer        ! Working hours available per line
  
  Load: array(LINES) of linctr        ! Workload constraints
  produce: array(PRODS) of mpvar      ! Quantity produced
 end-declarations

 initializations from 'i5pplan.dat'
  PROFIT DUR CAP
 end-initializations

! Objective: Total profit
 Profit:= sum(p in PRODS) PROFIT(p)*produce(p)
 
! Capacity constraints on lines
 forall(l in LINES) Load(l):=sum(p in PRODS) DUR(p,l)*produce(p) <= CAP(l)

! Solve the problem
 maximize(Profit)
 printsol 

! **** Allow transfer of working hours between lines ****

 declarations
  TRANSF: dynamic array(LINES,LINES) of integer ! 1 if transfer is allowed,
                                                ! 0 otherwise
  TMAX: array(LINES) of integer         ! Maximum no. of hours to transfer

  hours: array(LINES) of mpvar          ! Initial working hours per line
  transfer: dynamic array(LINES,LINES) of mpvar ! Hours transferred
 end-declarations

 initializations from 'i5pplan.dat'
  TRANSF TMAX
 end-initializations

 forall(k,l in LINES | exists(TRANSF(k,l))) create(transfer(k,l))

! Re-define capacity constraints on lines
 forall(l in LINES) Load(l):=sum(p in PRODS) DUR(p,l)*produce(p) <= hours(l)

! Balance constraints
 forall(l in LINES)
  hours(l)  = CAP(l) + sum(k in LINES) transfer(k,l) -
                      sum(k in LINES) transfer(l,k) 

! Limit on transfer
 forall(l in LINES) sum(k in LINES) transfer(l,k) <= TMAX(l)

! Solve the problem
 maximize(Profit)
 writeln("Solution with transfer of working hours:")
 printsol
 writeln("Transfers:")
 forall(l,k in LINES | exists(TRANSF(l,k)) and getsol(transfer(l,k))>0) 
  writeln(" ", l, "->", k, ": ", getsol(transfer(l,k)))

!-----------------------------------------------------------------

! Solution printing
 procedure printsol
  localsetparam("realfmt","%-8g")
  writeln("Total profit: ", getobjval)
  forall(p in PRODS)
   writeln("Product ", p, ": ", getsol(produce(p)))
  forall(l  in LINES)
   writeln("Line ", l, ": ", getsol(sum(p in PRODS) DUR(p,l)*produce(p))) 
 end-procedure
 
end-model

Back to examples browserPrevious exampleNext example