Lindo Systems

! The simplest possible work staffing model in LINGO ;
! Keywords: Staff scheduling, Workforce scheduling, Covering, Scheduling;
SETS:
 ! The generic data structures;
   PERIOD:  REQUIRED;
   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;
   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 
              1   1   1   0   0   0   0 ! 3 days/week;
              0   1   1   1   0   0   0 
              0   0   1   1   1   0   0   
              0   0   0   1   1   1   0
              0   0   0   0   1   1   1
              1   0   0   0   0   1   1
              1   1   0   0   0   0   1
              ;
     COST = 100 100 100 100 100 100 100
             70  70  70  70  70  70  70;
ENDDATA

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

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

! 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));
      );
ENDCALC