! Traffic light sychronization.
A set of traffic lights along a street all turn
red and green with the same cycle length T.
Associated with each light are the parameters:
  GT(i) = fraction of a cycle during which the 
         the light is green.
  DIST(i) = distance from light i-1 to light i.
We want to synchronize the lights  by determining:
  deltr(i) = fraction of a cycle after which light
             first turns green. Negative means the light
             turned green before time zero but is
             still green at time zero. We standardize
             by having deltr(1) = 0. Note:
               -GT(i) <= deltr(i) < 1 - GT(i),
! Keywords: Traffic light synchronization, routing;

SETS:
  LIGHT: DIST, GT, DELTR, ETF, LTF, ETB, LTB, MF, MB, TFZ, TBZ;
ENDSETS
DATA: ! Data taken from: Little, J.(1966),"The Synchronization of Traffic Signals by Mixed-Integer Linear Programming", Operations Research, vol. 14, pp. 568-594; LIGHT = 1..10; DIST = 0 168 213 335 213 244 198 122 213 137; GT = .53 .60 .60 .53 .52 .58 .60 .60 .60 .58; TL = 55; ! Shortest cycle time allowed in seconds; TU = 75; ! Longest cycle time allowed in seconds. Same cycle time must by used at all lights; SL = 13.4; ! Lowest speed allowed in meters/second; SU = 17.9; ! Highest speed allowed in meters/second; SD = .0121; ! Max possible change in seconds/meter of speed from one light to the next; MXFB = 1.1; ! = max ratio of forward bandwidth to backward; MNFB = 0.9; ! = min ratio of forward bandwidth to backward; ENDDATA ! Variables: T = cycle time used at all lights, Z = 1/T = cycles per second, TF(i) = time to go from i-1 to i, ETA(i) = early time that a vehicle can get to light i, starting in first green at light 1 and making through all the lights without stopping, For i > 1: = ETA(i-1) + TF(i), where DIST(i)/SU <= TF(i) <= DIST(i)/SL, ETF(i) = ETA(i)/T = ETA(i)*Z, = ETR(i-1) + TF(i)*Z, where DIST(i)*Z/SU <= TF(i)*Z <= DIST(i)*Z/SL, MF(i) = number of cycles completed by time our vehicle gets to light i, MF(i) = 0, 1, 2, ... Our vehicle made it through every green if for each i: There exists an MF(i) = 0, 1, 2,..., such that deltr(i)*T + MF(i)*T <= ETA(i) <= deltr(i)*T + MF(i)*T + GT(i)*T, or deltr(i) + MF(i) <= ETAR(i) <= deltr(i) + MF(i) + GT(i). This model assumes the the green and red time at a light are specified as a fixed fractions of the cycle length. It is easy to generalize to allow these times to be decision variables with upper and lower limits both on the fraction of the cycle and on the absolute time. For example, so that drivers do not get impatient on the cross streets you may want to put in an absolute upper limit on the green time. ; N = @SIZE(LIGHT); ! = number of lights; ! Max bandwidth = measure of number cars that can make it non-stop through all the lights in forward direction + backward direction; MAX = BANDF + BANDB; BANDF = LTF(N) - ETF(N); BANDB = LTB(1) - ETB(1); ! Upper limit on cycle length; Z >= 1/TU; ! Lower limit on cycle length; Z <= 1/TL; ! First consider traffic in forward/outbound direction; LTF(1) <= GT(1); DELTR(1) = 0; @FOR( LIGHT(i)| i #GT# 1: @BND( -GT(i), DELTR(i), 1-GT(i)); @GIN(MF(i)); ! Cannot arrive too early; ETF(i) >= DELTR(i) + MF(i); ! Cannot arrive too late; LTF(i) <= DELTR(i) + MF(i) + GT(i); ! Calc arrival time; ETF(i) = ETF(i-1) + TFZ(i); LTF(i) = LTF(i-1) + TFZ(i); ! Travel time, or speed, must be within limits; TFZ(i) <= DIST(i)*Z/SL; TFZ(i) >= DIST(i)*Z/SU; ); ! Put limits on speed changes between lights; @FOR( LIGHT(i)| i #GT# 2: TFZ(i)/DIST(i) - TFZ(i-1)/DIST(i-1) <= SD*Z; TFZ(i)/DIST(i) - TFZ(i-1)/DIST(i-1) >= -SD*Z; ); ! Now Backward/inbound direction along the street; @FREE( ETB(N)); @FREE( LTB(N)); ETB(N) >= DELTR(N); LTB(N) <= DELTR(N) + GT(N); @FOR( LIGHT(i)| i #LT# N: @GIN(MB(i)); @FREE( ETB(i)); @FREE( LTB(i)); ! Cannot arrive too early; ETB(i) >= DELTR(i) + MB(i); ! Cannot arrive too late; LTB(i) <= DELTR(i) + MB(i) + GT(i); ! Calc arrival time; ETB(i) = ETB(i+1) + TBZ(i); LTB(i) = LTB(i+1) + TBZ(i); ! Travel time, or speed, must be within limits; TBZ(i) <= DIST(i+1)*Z/SL; TBZ(i) >= DIST(i+1)*Z/SU; ); ! Optional, put limits on speed changes between lights; @FOR( LIGHT(i)| i #LT# N-1: TBZ(i)/DIST(i+1) - TBZ(i+1)/DIST(i+2) <= SD*Z; TBZ(i)/DIST(i+1) - TBZ(i+1)/DIST(i+2) >= -SD*Z; ); ! Optional, make bandwidths about equal; BANDF <= MXFB * BANDB; BANDF >= MNFB * BANDB;