Lindo Systems

! The simplest possible work staffing model in LINGO  (StaffPatSimp.lng);
! Keywords: Staff scheduling, Workforce scheduling, Covering, Scheduling,
     Chart, Graph, Bar chart;
SETS:
 ! The generic data structures;
   PERIOD:  REQUIRED, SUPPLIED;
   WORKPAT: NUM2RUN, COST;
   WXD( WORKPAT, PERIOD): ONRNOT;
ENDSETS

DATA:
  ! The circular week staffing problem;
 ! The names for the periods;
   PERIOD  = MON  TUE  WED  THU  FRI  SAT  SUN;
 ! Number folks required on duty each period;
   REQUIRED= 20   16   13   17   20   15   12;
 ! The possible work patterns. ONRNOT(i,j) = 1
   if workpattern i has someone on duty in period j.
   Each row is a candidate work pattern;
   ONRNOT =   1    1    1    1    1    0    0 ! Start 5 days on MON;
              0    1    1    1    1    1    0 ! Start 5 days on TUE;
              0    0    1    1    1    1    1   
              1    0    0    1    1    1    1
              1    1    0    0    1    1    1
              1    1    1    0    0    1    1
              1    1    1    1    0    0    1 
              ;
 ! Cost per unit of each work pattern;
     COST =   1    1    1    1    1    1    1;
!  Make SAT and SUN slight less attractive;
!     COST =   1 1.01 1.03 1.03 1.03 1.03 1.02;
! Can you predict for this data set, whether
  you can perfectly match SUPPLIED(j) = REQUIRED(j)
  for every day of the week j? ;
ENDDATA

SUBMODEL STAFFIT:
! Minimize cost of people used over all patterns;
MIN = OBJ;
  OBJ= @SUM( WORKPAT( i): COST(i)*NUM2RUN( i));

! For each period, the patterns used must cover that period;
@FOR( PERIOD( j): 
  SUPPLIED( j) = @SUM( WORKPAT( i): ONRNOT(i,j)*NUM2RUN(i));
  SUPPLIED(j) >= REQUIRED( j); ! Meet demand;
  );

! Can only hire integer people;
 @FOR(WORKPAT(j): @GIN(NUM2RUN(j)));
ENDSUBMODEL

CALC:
  @SOLVE(STAFFIT);

 ! Write a lil report;
  @FOR( WORKPAT(i) | NUM2RUN #GT# 0:
    @WRITE(' Put ', NUM2RUN(i),' people on the work pattern:', @NEWLINE(1));
      @FOR(PERIOD(j): @WRITE('   ',ONRNOT(i,j)));
    @WRITE( @NEWLINE(2));
      );
! Generare a bar chart of requied vs. supplied;
   @CHARTBAR('Staff Required vs. Supplied: Multi-Bar Chart, Cost= '+@FORMAT(OBJ,'6.2f'),
   'Day of week',         ! X axis label;
   '# People on duty',    ! Y axis label;
   'Required', REQUIRED,  ! Quantity 1;
   'Supplied', SUPPLIED); ! Quantity 2;
ENDCALC