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, featuresDifficulty
I‑1 Assigning personnel to machines: Assignment problem ****
formulation of maximin objective; heuristic solution + 2 different problems (incremental definition) solved, working with sets, while-do, forall-do, negative index values
I‑2 Scheduling nurses ***
2 problems, using mod to formulate cyclic schedules; forall-do, set of integer
I‑3 Establishing a college timetable ***
many specific constraints, tricky (pseudo) objective function; finalize
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 **
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





i1assign.mos

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

   file i1assign.mos
   `````````````````
   Assigning workers to machines
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002
*******************************************************!)

model "I-1 Personnel assignment"
 uses "mmxprs"

 forward procedure parallel_heur
 forward procedure print_sol(text1,text2:string)

 declarations
  PERS = 1..6                        ! Personnel
  MACH = 1..6                        ! Machines
  OUTP: array(PERS,MACH) of integer  ! Productivity
 end-declarations

 initializations from 'i1assign.dat'
  OUTP
 end-initializations

! **** Heuristic solution for parallel assignment ****
 parallel_heur
 
! **** Exact solution for parallel assignment ****

 declarations
  assign: array(PERS,MACH) of mpvar  ! 1 if person assigned to machine,
                                     ! 0 otherwise
 end-declarations

! Objective: total productivity
 TotalProd:= sum(p in PERS, m in MACH) OUTP(p,m)*assign(p,m)

! One machine per person
  forall(p in PERS) sum(m in MACH) assign(p,m) = 1

! One person per machine
  forall(m in MACH) sum(p in PERS) assign(p,m) = 1

! Solve the problem
 maximize(TotalProd)
 print_sol("Exact solution (parallel assignment)", "Total")

! **** Exact solution for serial machines ****

 declarations
  pmin: mpvar                        ! Minimum productivity
 end-declarations

! Calculate minimum productivity
 forall(p in PERS) sum(m in MACH) OUTP(p,m)*assign(p,m) >= pmin

 forall(p in PERS, m in MACH) assign(p,m) is_binary

! Solve the problem
 maximize(pmin)
 print_sol("Exact solution (serial machines)", "Minimum")
 
!-----------------------------------------------------------------

! Heuristic solution for parallel assignment
 procedure parallel_heur
  declarations
   ALLP, ALLM: set of integer        ! Copies of sets PERS and MACH
   HProd: integer                    ! Total productivity value
   pmax,omax,mmax: integer
  end-declarations

 ! Copy the sets of workers and machines
  forall(p in PERS) ALLP+={p}
  forall(m in MACH) ALLM+={m}

 ! Assign workers to machines as long as there are unassigned persons
  while (ALLP<>{}) do
   pmax:=0; mmax:=0; omax:=0

 ! Find the highest productivity among the remaining workers and machines
   forall(p in ALLP, m in ALLM)
    if OUTP(p,m) > omax then
     omax:=OUTP(p,m)
     pmax:=p; mmax:=m
    end-if   

   HProd+=omax                       ! Add to total productivity
   ALLP-={pmax}; ALLM-={mmax}        ! Remove person and machine from sets
  
   writeln("  ",pmax, " operates machine ", mmax, " (", omax, ")")
  end-do

  writeln("  Total productivity: ", HProd)
 end-procedure

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

! Solution printing
 procedure print_sol(text1,text2:string)
  writeln(text1,":")
  forall(p in PERS) do
   mp:=round(getsol(sum(m in MACH) m*assign(p,m)))
   writeln("  ",p, " operates machine ", mp, " (", OUTP(p,mp), ")")
  end-do 
  writeln("  ", text2, " productivity: ", getobjval)
 end-procedure
 
end-model

Back to examples browserPrevious exampleNext example