MODEL:
! The dock or gate assignment problem with possible delays. (GateAssignWithDelays)
A number of vehicles (trucks, airplanes...)
arrive over time at an exchange facility.
The facility has a number of docks or gates.
Each gate can handle at most one vehicle at a time.
We would like to assign vehicles to gates so that
 at most one vehicle is assigned to a specific gate
at a specific instance,
 there is very little delay,
 the value of the assignments is maximized.
 Arriving vehicles can be temporarily delayed in
the "penalty box" if a gate is not available.
 Additional realistic features not included:
disallowing certain, e.g., large, vehicles to
be at adjacent gates;
! Keywords: Assignment, Gate assignment, Dock assignment, Multi-criteria;

SETS:
  VEH: ARVT, LEVT, DELAY;
  GATE;
  VXG( VEH, GATE) : VAL, Y;
  VXVL( VEH, VEH) | &1 #GT# &2: BEFORE;
ENDSETS
DATA: ! Vehicles, their arrival times, and their leave or departure times; VEH ARVT LEVT = V01 615 650 V02 617 651 V03 630 700 V04 644 720 V05 651 731 V06 702 740 V07 703 739 V08 706 750 V09 707 748 V10 708 752 V11 710 749; ! The available gates; GATE = G01 G02 G03 G04; ! The value of assigning vehicle v to gate g; VAL = 3 4 4 3 4 6 7 3 5 5 5 5 4 6 5 3 2 6 7 3 6 4 2 3 3 6 7 3 4 6 6 3 1 9 7 2 4 6 7 3 2 1 4 3; MAXDELAY = 30; ! Max allowed delay; ENDDATA ! Variables: Y(v,g) = 1 if vehicle v is assigned to gate g, DELAY(v) = delay incurred by vehicle v, so v occupies its gate from ARVT(v) + DELAY(v) to LEVT(v) + DELAY(v), BEFORE(v1,v2) = 0 if v1 precedes v2 at the same gate, 1 if v2 precedes v1. ; ! Various objectives; SUBMODEL MAX_ASSG: ! Maximize number vehicles assigned; MAX = OBJASG; ENDSUBMODEL
SUBMODEL MIN_DELAYS: ! Minimize total delays; MIN = OBJTOTD; ENDSUBMODEL
SUBMODEL MINMAX_DELAY: ! Minimize maximum delay; MIN = OBJMAXD; ENDSUBMODEL
SUBMODEL MAX_VALUE: ! Maximize the value of the assignments; MAX = OBJVALA; ENDSUBMODEL
SUBMODEL GATE_CONSTRAINTS: ! The objective of number of vehicles assigned a gate; OBJASG = @SUM( VXG(v,g): Y(v,g)); ! Objective of total delay; OBJTOTD = @SUM( VEH(v): DELAY(v)); ! Objective of max delay; @FOR( VEH(v): OBJMAXD >= DELAY(v); ); ! Objective of value of assignments; OBJVALA = @SUM( VXG(v,g): VAL( v, g)* Y( v, g)); ! Each vehicle must be assigned to at most one gate; @FOR( VEH( v): @SUM( VXG( v, g): Y( v, g)) <= 1; ); ! Consider v and v2 that might conflict if assigned to the same gate; @FOR( VXVL(v,v2) | LEVT( v) + MAXDELAY #GT# ARVT( v2) #AND# LEVT( v2) + MAXDELAY #GT# ARVT( v): ! Either: v2 departs before v arrives (BEFORE(v,v2) = 0), or, v departs before v2 arrives (BEFORE(v,v2) = 1); @FOR( GATE( g): ! This constraint applies if v departs g before v2 arrives at g (BEFORE( v, v2) = 0); LEVT( v) + DELAY( v) <= ARVT( v2) + DELAY( v2) + (LEVT( v) + MAXDELAY - ARVT( v2))* ( 2 - Y( v, g) - Y( v2, g) + BEFORE( v, v2)); ! This constraint applies if v2 departs g before v arrives at g (BEFORE( v, v2) = 1); LEVT( v2) + DELAY( v2) <= ARVT( v) + DELAY( v) + (LEVT( v2) + MAXDELAY - ARVT( v))* ( 2 - Y( v, g) - Y( v2, g) + (1-BEFORE( v, v2))); ); ); @FOR( VEH( v): DELAY( v) <= MAXDELAY); ! The 0/1 variables; @FOR( VXG( v, g): @BIN( Y( v, g)); ); @FOR( VXVL( v, v2): @BIN( BEFORE( v, v2))); ! Fix/Constrain the various criteria; ! Number vehicles assigned; OBJASG >= OBJASGF; ! Total delays; OBJTOTD <= OBJTOTDF; ! Max delay; OBJMAXD <= OBJMAXDF; ENDSUBMODEL
CALC: @SET( 'TERSEO', 2); ! Turn off default messages; @SET('OROUTE',1); ! Route every line immediately to the window; ! First find max vehicles assignable; @SOLVE( MAX_ASSG, GATE_CONSTRAINTS); OBJASGF = OBJASG; ! Fix number assigned; @WRITE( OBJASG,' = Total vehicles assigned.',@NEWLINE(1)); ! Next minimize total delays; @SOLVE( MIN_DELAYS, GATE_CONSTRAINTS); OBJTOTDF = OBJTOTD; ! Cap total delays; @WRITE( OBJTOTD,' = Total delay.',@NEWLINE(1)); ! Next minimize maximum delay; @SOLVE( MINMAX_DELAY, GATE_CONSTRAINTS); OBJMAXDF = OBJMAXD; ! Cap max delay; @WRITE( OBJMAXD,' = Maximum delay.',@NEWLINE(1)); @SOLVE( MAX_VALUE, GATE_CONSTRAINTS); @WRITE( OBJVALA,' = Value of assignments.',@NEWLINE(1)); ! Display a short report; @WRITE('Vehicle Gate Arv_time Depart_time Delay',@NEWLINE(1)); @FOR( VEH(v) | @SUM( GATE(g): Y(v,g)) #GT# 0.5: @FOR( GATE(g) | Y(v,g) #GT# 0.5: ATGATE = g;); @WRITE( ' ',VEH(v),' ', ATGATE,' ',@ROUND( ARVT(v)+DELAY(v), 0), ' ',@ROUND( LEVT(v)+DELAY(v), 0),' ',@ROUND( DELAY(v),0), @NEWLINE(1)); ); ENDCALC END