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





i2nurse.mos

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

   file i2nurse.mos
   ````````````````
   Work schedule for nurses
   
   We must determine the schedule for nurses in a hospital. 
   A working day is divided into twelve two-hour periods. 
   The personnel requirement for every period is given. 
   The number of working hours and break hours per day is 
   also known. How many nurses should be assigned to each 
   period to satisfy the personnel requirements and minimize 
   the total number of nurses? For a second problem, a 
   maximum number of total nurses is defined but nurses can
   work overtime. Determine the schedule of nurses minimizing
   the total number of nurses working overtime.

   The demand of a particular period can be covered with nurses
   who start working in such a period, and with nurses starting
   in some preceding periods based on the working hours and 
   breaks. A generic demand constraint is built using the 'mod'
   operator to formulate cyclic schedules. 
   For question 2, a new decision variable is introduced to model 
   overtime, so demand constraints are adjusted accordingly.

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

model "I-2 Scheduling nurses"
 uses "mmxprs"

 declarations
  NT = 12                        ! Number of time periods
  TIME = 0..NT-1
  WORK: set of integer           ! Nurses started in other time periods
                                 ! that are working during a period
  
  REQ: array(TIME) of integer    ! Required number of nurses per time period
  
  Period: array(TIME) of linctr  ! Constraints on personnel per period
  start: array(TIME) of mpvar    ! Nurses starting work in a period
 end-declarations

 initializations from 'i2nurse.dat'
  REQ
 end-initializations

 WORK:= {0, -1, -3, -4}

! Objective: total personnel required
 Total:= sum(t in TIME) start(t)

! Nurses working per time period
 forall(t in TIME) Period(t):= sum(i in WORK) start((t+i+NT) mod NT) >= REQ(t) 

 forall(t in TIME) start(t) is_integer

! Solve the problem
 minimize(Total)
 
! Solution printing
 writeln("Total personnel: ", getobjval)
 forall(t in TIME) 
  writeln(strfmt(t*2,2), ":00-",strfmt((t+1)*2,2), ":00 : starting: ", 
          getsol(start(t)),
          " total: ", getsol(sum(i in WORK) start((t+i+NT) mod NT)))

! **** Second problem: minimize overtime with given staff level ****

 declarations
  NUM: integer                   ! Available total staff
  overt: array(TIME) of mpvar    ! Nurses working overtime
 end-declarations

 initializations from 'i2nurse.dat'
  NUM
 end-initializations

! Objective: total overtime worked
 TotalOvert:= sum(t in TIME) overt(t)

! Nurses working per time period
 forall(t in TIME) 
  Period(t):= overt((t-5+NT) mod NT) + sum(i in WORK) start((t+i+NT) mod NT) >= 
              REQ(t) 

! Limit on total number of nurses
 Total <= NUM

 forall(t in TIME) do
  overt(t) is_integer
  overt(t) <= start(t)
 end-do 

! Solve the problem
 minimize(TotalOvert)
 
! Solution printing
 writeln("\nPersonnel working overtime: ", getobjval)
 forall(t in TIME) 
  writeln(strfmt(t*2,2), ":00-",strfmt((t+1)*2,2), ":00 : starting: ", 
          getsol(start(t)), " total: ", getact(Period(t)), 
          " overtime: ", getsol(overt((t-5+NT) mod NT)))

end-model

Back to examples browserPrevious exampleNext example