Lindo Systems

! The simplest possible work staffing model in LINGO  (StaffPatSimp.lng);
! Keywords: Staff scheduling, Workforce scheduling, Covering, Scheduling,
     Chart, Graph, Bar chart, ChartBar;
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= 19   17   15   19   17   14   12;
 ! The possible work patterns. ONRNOT(i,j) = 1
   if workpattern i has someone on duty in period j;
   ONRNOT =   1    1    1    1    1    0    0 ! 5 days/week;
              0    1    1    1    1    1    0 
              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 slightly less attractive;
     COST =   1 1.01 1.05 1.05 1.05 1.05 1.04;
!  Make SUN more attractive;
!     COST =   1   1  0.999 0.999 0.999 0.999 0.999;
ENDDATA

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

! For each period j, 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));
      );
! Generate a bar chart of Required vs. Supplied;
   @CHARTBAR('Staff Required vs. Supplied: Multi-Bar Chart, Cost= '
     +@FORMAT(OBJ,'6.1f'),! Title of chart;
   'Day of week',         ! X axis label;
   '# People on duty',    ! Y axis label;
   'Required', REQUIRED,  ! Quantity 1;
   'Supplied', SUPPLIED); ! Quantity 2;
ENDCALC