Multi-Site Staff Scheduling with Excel - The Details
In the model's sets section:
SETS:
SITES / PLUTO, MARS, SATURN/;
DAYS / MON TUE WED THU FRI SAT SUN/:
NEEDS, START, ONDUTY;
ENDSETS
we declare two sets. The first set is our set of three sites followed by a set containing the days of the week. The days of the week set has three associated attributes: NEEDS, START, and ONDUTY, representing the staffing needs, the number of workers to start on each day of the week, and the total number of workers on duty each day.
Next, we declare a submodel that contains the staffing model that will be applied to each of the three sites:
SUBMODEL STAFF:
[OBJROW] MIN = @SUM( DAYS: START);
@FOR( DAYS( D):
ONDUTY( D) = @SUM( DAYS( D2) | D2 #LE# 5:
START( @WRAP( D - D2 + 1, @SIZE( DAYS))));
ONDUTY( D) >= NEEDS( D);
);
@FOR( DAYS: @GIN( START));
ENDSUBMODEL
The objective function minimizes the total number of employees hired at the site. This is then followed by an @FOR loop over the days of the week that a) computes the number of employees on duty each day, and b) requires the number on duty to equal, or exceed, the number required on each day. We also require the number starting on each day to be an integer value using the @GIN statement.
The following calc section:
CALC:
@SET( 'TERSEO', 2);
@FOR( SITES( S):
NEEDS = @OLE( '\LINGO12\SAMPLES\DOGS.XLS',
SITES( S)+'NEEDS');
@SOLVE( STAFF);
@SOLU( 0, ONDUTY, ' On Duty Report: ' + SITES( S));
@OLE( , SITES( S)+'START', SITES( S)+'ONDUTY',
SITES( S)+'TOTAL') = START, ONDUTY, OBJROW;
);
ENDCALC
starts off by restricting the amount of LINGO's output by setting the TERSEO parameter to 2, which essentially eliminates all of LINGO"s output.
Next, we construct an @FOR loop that loops over the three sites, allowing us to solve the submodel STAFF for each site. The first statement in the loop is an @OLE statement that reads the staffing requirements from the appropriate tab of the workbook and places the requirements into the NEEDS attribute. If you look at the workbook closely, you'll see that there are three ranges named "SaturnNeeds", "PlutoNeeds" and "MarsNeeds" that contain the staffing requirements for each of the respective sites. We are building each of these range names via the SITES(S)+'NEEDS' argument in the @OLE function call.
Once the staffing requirements are loaded, we invoke the @SOLVE command to solve the staffing model for the current site. The @SOLU command prints out a small solution report to the screen showing the number of workers on duty each day for each of the sites.
At the bottom of the calc section, the last @OLE call sends the solution back to the workbook. Note that for each site there are three ranges titled "<site_name>START", "<Isite_name>ONDUTY" and "<site_name>TOTAL", where we return the daily number of workers to start, the number on duty each day, and the total number of employees required for the entire week. Note also that the workbook name was omitted in the call. When the workbook name is omitted, LINGO simply uses the current workbook in Excel. Given that we specified the workbook name in the original call to @OLE, it should now be the current workbook, thereby allowing us to omit its name in the final call.
If you solve the model, you'll see that the tab for each of the three sites contains the number of workers to start each day, the total number on duty each day, and the total number of employees required. For the Saturn site, the tab will resemble the following: