ࡱ> Root EntryRoot Entry*0_^@}Contents4 {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}} {\colortbl ;\red0\green0\blue255;\red0\green0\blue0;\red0\green175\blue0;} \viewkind4\uc1\pard\cf1\f0\fs20 MODEL\cf2 : \par \par \cf3 ! Staffing example: \par Step 1: \par - Minimize total cost \par Step 2: \par - Fix costs to their level from Step 1 \par - Solve to minimize max staff overage \par on any given day, thereby spreading \par excess staff through the week \par Step 3: \par - Fix max overage to it's level from \par Step 2 \par - Solve to minimize the number working \par on a Sunday \par ;\cf2 \par \par \cf1 SETS\cf2 : \par DAY / MON, TUE, WED, THU, FRI, SAT, SUN/ : \par NEED, START, COST, EXCESS; \par \cf1 ENDSETS\cf2 \par \par \cf1 DATA\cf2 : \par NEED = 18, 15, 12, 16, 19, 14, 12; \par COST = 200, 200, 200, 200, 200, 200, 200; \par \cf1 ENDDATA\cf2 \par \par \cf1 SUBMODEL\cf2 OBJ_COST: \par \cf1 MIN\cf2 = TTL_COST; \par \cf1 ENDSUBMODEL\cf2 \par \par \cf1 SUBMODEL\cf2 OBJ_MAX_EXCESS: \par \cf1 MIN\cf2 = MAX_EXCESS; \par \cf1 ENDSUBMODEL\cf2 \par \par \cf1 SUBMODEL\cf2 OBJ_MIN_SUNDAY_STARTS: \par \cf1 MIN\cf2 = EXCESS( \cf1 @INDEX\cf2 ( DAY, SUN)); \par \cf1 ENDSUBMODEL\cf2 \par \par \cf1 SUBMODEL\cf2 BASE: \par \cf3 ! Compute cost;\cf2 \par TTL_COST = \cf1 @SUM\cf2 ( DAY( D) : START( D) * COST( D)); \par \par \cf3 ! The constraints;\cf2 \par \cf1 @FOR\cf2 ( DAY( D): \par \cf1 @SUM\cf2 ( DAY( COUNT)| COUNT #LE# 5: \par START( \cf1 @WRAP\cf2 ( D - COUNT + 1, \cf1 @SIZE\cf2 ( DAY)))) - \par EXCESS( D)= NEED( D) \par ); \par \par \cf3 ! Computes the maximum staff excess;\cf2 \par \cf1 @FOR\cf2 ( DAY( D): MAX_EXCESS >= EXCESS( D)); \par \par \cf3 ! Starts must be integral;\cf2 \par \cf1 @FOR\cf2 ( DAY: \cf1 @GIN\cf2 ( START)); \par \par \cf1 @BND\cf2 ( 0, TTL_COST, BNDU_COST); \par \cf1 @BND\cf2 ( 0, MAX_EXCESS, BNDU_MAX_EXCESS); \par \cf1 ENDSUBMODEL\cf2 \par \par \cf1 CALC\cf2 : \par \cf3 !Run in quiet mode;\cf2 \par \cf1 @SET\cf2 ( 'TERSEO', 2); \par \par \cf3 !Free up bounds;\cf2 \par BNDU_COST = 1.E10; \par BNDU_MAX_EXCESS = 1.E10; \par \par \cf3 !Solve to minimize cost;\cf2 \par \cf1 @SOLVE\cf2 ( OBJ_COST, BASE); \par \par \cf1 @WRITE\cf2 ( 'Solution 1 - min cost:', \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' Start: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( START, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' On Duty: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( NEED + EXCESS, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' Excess: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( EXCESS, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 2)); \par \par \cf3 !Fix TTL_COST to optimal value;\cf2 \par BNDU_COST = TTL_COST; \par \par \cf3 !Re-solve to minimize the max excess staff on any given day \par in order to spread any excess staff throughout the week;\cf2 \par \cf1 @SOLVE\cf2 ( OBJ_MAX_EXCESS, BASE); \par \par \cf1 @WRITE\cf2 ( 'Solution 2 - min cost / min max excess:', \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' Start: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( START, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' On Duty: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( NEED + EXCESS, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' Excess: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( EXCESS, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 2)); \par \par \cf3 !Fix max excess to optimal level;\cf2 \par BNDU_MAX_EXCESS = MAX_EXCESS; \par \par \cf3 !Re-solve to minimize total workers on Sundays;\cf2 \par \cf1 @SOLVE\cf2 ( OBJ_MIN_SUNDAY_STARTS, BASE); \par \par \cf1 @WRITE\cf2 ( 'Solution 3 - min cost / min max excess / min Sunday:', \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' Start: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( START, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' On Duty: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( NEED + EXCESS, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 1)); \par \cf1 @WRITE\cf2 ( ' Excess: '); \par \cf1 @WRITEFOR\cf2 ( DAY: \cf1 @FORMAT\cf2 ( EXCESS, '6.0f')); \par \cf1 @WRITE\cf2 ( \cf1 @NEWLINE\cf2 ( 2)); \par \par \cf1 ENDCALC\cf2 \par \par \cf1 END\cf2 \par \par \par \par }