Skip to content

← Data and analysis

Why Do Traffic Jams Appear Out of Nowhere?

Topic 14 · Grades 9–12 · Traffic models

You need lists, loops and the random module in Python (Grade 9); stepping a simulation forward is explained here, and Grade 11 has the whole story.

What this builds on from class
In this unit 8 sections
  1. Try it
  2. How it works
  3. Program it
  4. What your program shows
  5. Going further still
  6. Challenges
  7. Questions
  8. Where to go next

You are in a microbus on a busy road, Kathmandu’s Ring Road perhaps, or the highway down to Mugling. The bus slows, stops, crawls for a minute, then speeds up again. You look out for the reason: an accident, a crossing, a police checkpoint, a cow. There is nothing. A few minutes later it happens again. Where do these jams come from, and why is there nothing at the front of them?

The road below is a ring, 750 m round, with cars that follow four simple rules. Tap one car to make it brake for a moment, then let it drive on.

Try it

Cars on a ring road

Press Play, wait until everyone is cruising, then tap any car (or press Brake). Watch the red cars, not the one you tapped.

counting linecars drive this way750 m roundtap a car to brakeringed car
Drivers:
Time
0:00
Average speed
135 km/h
Stopped
0 of 14
Cars a minute
–

14 cars cruise at 135 km/h with room ahead. Press Play, then tap a car.

Fourteen cars are cruising at top speed, each with room ahead. One driver brakes to a stop for one second, then drives on. What do you think happens?

Pick an answer to see why.

You need lists and loops in Python (Grade 9) and random.random() from Python’s random module, as in Grade 9, Algorithms that use chance. The idea of a simulation that moves one step at a time is explained here; Grade 11, Modelling and Simulation has the whole story.

Try it

Play with the ring road, and read the readouts as well as the picture.

  • Fourteen cars, one brake. Before the brake, every car is green and the readout says 135 km/h. After it, a red knot appears and stays. Look at the ringed car: it drives into the back of the jam, waits, and leaves from the front. The jam is made of different cars all the time, like a wave on a pond.
  • Which way? The cars drive clockwise. Watch where the red knot is after half a minute, and after a minute. It has moved anticlockwise, slowly.
  • The cost. After a few minutes, read Average speed and Cars a minute. Then press Reset, play without braking, and read them again.
  • Nine cars. Set Cars to 9 and brake one. The jam forms, and then it melts away: usually within a minute or two, sometimes a few seconds, everyone is cruising again.
  • Perfect drivers. Fourteen cars again, with Drivers: Perfect. Brake one. The jam clears in a quarter of a minute or so.
  • Too many. Set Cars to 24 and press Play without touching anything.

How it works

A road made of cells

In 1992 two physicists at the University of Cologne in Germany, Kai Nagel and Michael Schreckenberg, wanted a model of traffic simple enough for a computer to run a whole motorway’s cars, fast. They cut a lane into cells, each 7.5 m long, about the room a car takes up in a queue, and time into steps of one second. A cell is either empty or has one car in it, and a car’s speed is a whole number: how many cells it moves in a step.

  • Speed 1 is one cell a second: 7.5 m/s, which is 27 km/h.
  • The top speed is 5 cells a step: 37.5 m/s, or 135 km/h, a fast motorway.

The widget is 100 cells of this road bent into a ring, so a car that drives off the end comes back in at the start. That is why its readouts say 750 m: 100 × 7.5 m.

Four rules

Every step, for every car at once, these four rules decide its new speed and where it goes:

  1. Speed up. If it is below top speed, its speed goes up by 1.
  2. Don’t hit the car in front. If there are fewer empty cells ahead than its speed, its speed drops to the number of empty cells.
  3. Dawdle. If it is moving, then with a chance of one in two its speed goes down by 1.
  4. Move. It moves forward that many cells.

Rule 3 is the human part. Real drivers don’t speed up perfectly: someone looks at a phone, someone is slow to press the pedal, someone brakes a little when they didn’t need to. In Nagel and Schreckenberg’s model this happens at random, like a coin toss for each driver each second.

Our cars have one more rule, from a version of the model Nagel studied with Maya Paczuski in 1995: a car already cruising at top speed, with at least 5 empty cells ahead, just keeps going. Drivers on an open road hold their speed well; it is getting back up to speed, after slowing down, that they do sloppily. Nagel and Paczuski called this the cruise control limit: on an open road every car holds its speed as if a car’s cruise control button were on. It is why, in the widget, cars that are cruising never jam unless something disturbs them.

Each rule looks only at the car itself and the cells just ahead of it. Nothing in the rules mentions a jam. Jams are what many cars following them together do: something that is in the whole and in no single part, which is called an emergent behavior.

In the model, a car’s speed is 3 and there are 2 empty cells in front of it. It doesn’t dawdle this step. How far does it move?

Pick an answer to see why.

Why one brake is enough

When one car stops, the car behind it, cruising at 5, has to stop too; and so does the one behind that, if it was close. Now they have to get going again, and rule 3 makes them slow about it: half the time a stopped driver doesn’t move off this second. Meanwhile the cars behind keep arriving at top speed. If cars arrive at the back of the jam faster than they leave from its front, the jam grows; if slower, it shrinks and dies. Which wins depends on how close together the cars were: on how many cars share the road.

Program it

All in Python. The pictures use pixels, this page’s own module for showing a list of rows as a picture (on your own computer you would use a library such as Pillow).

Step 1: the four rules on a list

The road is a list with one item for each cell: None for an empty cell, or the speed of the car in it. step makes the road one second later. It builds a new list, so that every car decides from the road as it was, all at once, as the rules say.

import random VMAX = 5      # top speed: 5 cells (37.5 m) a stepP = 0.5       # the chance that a driver dawdles def gap_ahead(road, i):    # empty cells in front of the car in cell i, looking at most VMAX ahead    for d in range(1, VMAX + 1):        if road[(i + d) % len(road)] is not None:            return d - 1    return VMAX def step(road):    new = [None] * len(road)    for i in range(len(road)):        v = road[i]        if v is None:            continue        gap = gap_ahead(road, i)        if not (v == VMAX and gap == VMAX):      # cruising? then just keep going            v = min(v + 1, VMAX)                  # 1. speed up            v = min(v, gap)                       # 2. don't hit the car in front            if v > 0 and random.random() < P:                v = v - 1                         # 3. dawdle        new[(i + v) % len(road)] = v              # 4. move    return new def show(road):    return ''.join('.' if v is None else str(v) for v in road) random.seed(1)road = [None] * 42for k in range(7):    road[k * 6] = VMAX       # seven cars, 6 cells apart, all at top speedroad[30] = 0                 # the car in cell 30 brakes to a stopfor t in range(16):    print(f'{t:2} {show(road)}')    road = step(road)

Output

 0 5.....5.....5.....5.....5.....0.....5..... 1 .....5.....5.....5.....5.....50..........5 2 ....5.....5.....5.....5.....50.1.......... 3 .........5.....5.....5.....50.1.1......... 4 ..............5.....5.....500.0...2....... 5 ...................5.....500.10.....2..... 6 ........................500.100........3.. 7 .4......................000.000........... 8 .....4..................00.100.1.......... 9 .........4..............00.00.1..2........10 .............4..........00.00..1...2......11 .................4......00.00...1....2....12 .....................4..00.00.....2.....3.13 .3.....................200.0.1.......3....14 ....3..................00.1.1..2........3.15 ..4.....4..............0.10...2...3.......

Each line is the road a second later; each digit is a car and its speed. Read a 5 going down the lines: it moves 5 cells to the right each time, wraps round the end, and comes back in at the left. Now look at the zeros. The braked car is in cell 30 at the start; by line 7 the stopped cars are spread over cells 24 to 30; by line 15 the last zero is in cell 23. The cars drive right; the zeros go left.

(i + d) % len(road) is what makes the road a ring: the cell after the last one is cell 0. random.seed(1) makes the page’s run and yours dawdle the same way; take it out and the details change every run, but not the shape.

Step 2: a picture of the jam

Text gets hard to read for a long road. So now the widget’s road, 100 cells with 14 cars, and each line of show becomes a row of colored squares: white for an empty cell, green for a car at top speed, orange for a slower one, red for a stopped one. Time runs down the picture, two minutes of it.

from traffic import *from pixels import show_grid COLORS = {'.': 'white', '0': 'red', '1': 'darkorange', '2': 'darkorange',          '3': 'orange', '4': 'orange', '5': 'green'} random.seed(1)road = ring(100, 14)road[0] = 0                  # the car in cell 0 brakespicture = []for t in range(120):    picture.append(show(road))    road = step(road)show_grid(picture, COLORS)

Picture

A picture 100 squares wide and 120 tall, white with lines of colored squares: green lines slant steeply down to the right, cars driving forward; from the top right a red and orange band runs down and to the left, slowly, the jam moving backwards, and the green lines bend and break where they cross it.

Each car draws a line slanting down to the right: it moves right as time goes down. The jam is the red band, and it slants the other way. Where a car’s line meets the band it turns red and nearly upright (stopped, time passing, no cells covered), then leaves the band and speeds up green again. Change 14 to 9 and run it: the red band fades out.

How fast does the jam go? Follow it: each second, find the stopped car nearest to where the jam was, and add up how far it moved. A move is counted the short way round the ring, so that a jam moving from cell 1 back to cell 98 has moved −3 cells, not +97.

from traffic import * def short_way(a, b):    # cells from a to b the short way round a ring of 100: -50 to 49    return (b - a + 50) % 100 - 50 random.seed(1)road = ring(100, 14)road[0] = 0jam = 0                      # where the jam is: the braked car's cellmoved = 0for t in range(600):         # ten minutes    road = step(road)    stopped = [i for i in range(100) if road[i] == 0]    if stopped:        nearest = min(stopped, key=lambda i: abs(short_way(jam, i)))        moved += short_way(jam, nearest)        jam = nearest speeds = [v for v in road if v is not None]print('The jam moved', moved, 'cells in 600 seconds:', round(moved * 7.5 * 3.6 / 600, 1), 'km/h')print('The cars now average', round(sum(speeds) / len(speeds) * 27), 'km/h')

Output

The jam moved -143 cells in 600 seconds: -6.4 km/hThe cars now average 35 km/h

key=lambda i: … tells min to pick the stopped cell whose distance from the jam is smallest (lambda makes a small function on the spot). Cells a second times 7.5 m is meters a second, and times 3.6 is km/h.

The minus sign is the backwards. The cars drive forwards at up to 135 km/h, and the jam drives backwards at about 6 km/h, a walking pace. Run it with other seeds (random.seed(2), 3…) and you will get between about 5 and 11 km/h. Real jams go backwards faster, at about 15 km/h, give or take 5, and at much the same speed on all the motorways of a country; our model’s drivers are slow to set off (a 1-in-2 chance each second of not moving), so its jams are slow too.

Step 3: how many cars can the ring take?

With nine cars the jam melted; with fourteen it stayed. Where is the line? For each number of cars from 8 to 16, brake one car on 10 different runs and see whether the jam is still there after 1,000 seconds. “Still there” means some car is below top speed.

from traffic import * def jammed(road):    # is any car below top speed?    return any(v is not None and v < VMAX for v in road) random.seed(1)for cars in range(8, 17):    lasting = 0    for run in range(10):        road = ring(100, cars)        road[0] = 0        for t in range(1000):            road = step(road)            if not jammed(road):                break        else:            lasting += 1     # the loop never broke: still jammed after 1,000 s    print(f'{cars:2} cars: still jammed after 1,000 s in {lasting:2} of 10 runs')

Output

 8 cars: still jammed after 1,000 s in  0 of 10 runs 9 cars: still jammed after 1,000 s in  0 of 10 runs10 cars: still jammed after 1,000 s in  0 of 10 runs11 cars: still jammed after 1,000 s in  2 of 10 runs12 cars: still jammed after 1,000 s in  7 of 10 runs13 cars: still jammed after 1,000 s in 10 of 10 runs14 cars: still jammed after 1,000 s in 10 of 10 runs15 cars: still jammed after 1,000 s in 10 of 10 runs16 cars: still jammed after 1,000 s in 10 of 10 runs

A for loop’s else runs only when the loop finished without a break: here, when the jam never cleared. It takes a second or two on a phone.

Ten cars and the jam died in every run; thirteen and it never did. In between is a narrow band where it is a matter of luck. The line is sharp: 10 to 13 cars on 750 m is 13 to 17 cars a kilometer, and even at 13 the cars are 58 m apart, a second and a half of driving at 135 km/h. Below the line, a brake is forgotten. Above it, every one of these roads could have cruised forever (up to 16 cars there is room for all of them at top speed) and one brake ends that for good.

Step 4: what a jam costs

How many cars a minute get round the ring? Each second a car moves its speed in cells, passing that many of the 100 places between cells. So all the cars together pass sum(speeds) places, and each place, on average, is passed by sum(speeds) / 100 cars a second. Add that up over a minute, after ten minutes to settle, for roads with and without a brake.

from traffic import * def cars_a_minute(road):    # ten minutes to settle, then a minute of counting    passed = 0    for t in range(660):        road = step(road)        if t >= 600:            passed += sum(v for v in road if v is not None)    return round(passed / len(road)) random.seed(1)print('cars a minute past any point on the ring')for cars in range(4, 41, 4):    smooth = cars_a_minute(ring(100, cars))    road = ring(100, cars)    road[0] = 0    braked = cars_a_minute(road)    print(f'{cars:2} cars, no brake  {smooth:2} {"#" * (smooth // 2)}')    print(f'          one brake {braked:2} {"#" * (braked // 2)}')

Output

cars a minute past any point on the ring 4 cars, no brake  12 ######          one brake 12 ###### 8 cars, no brake  24 ############          one brake 24 ############12 cars, no brake  36 ##################          one brake 36 ##################16 cars, no brake  48 ########################          one brake 19 #########20 cars, no brake  19 #########          one brake 17 ########24 cars, no brake  18 #########          one brake 20 ##########28 cars, no brake  16 ########          one brake 15 #######32 cars, no brake  16 ########          one brake 14 #######36 cars, no brake  15 #######          one brake 16 ########40 cars, no brake  15 #######          one brake 14 #######

Up to 16 cars, more cars carry more traffic: 48 cars a minute with 16, as long as no one brakes. One brake on that road and it carries 19, fewer than with 8 cars. And from 20 cars on, there is no room for everyone at top speed; jams come without any brake at all, and the road carries less and less as it fills. (At 12 cars the brake’s jam happened to clear on this run; Step 3 says it often doesn’t.)

What your program shows

  • One brake makes a jam that outlives it: with 13 or more cars on the ring, the jam was still there after 1,000 seconds in every run, long after the braking car had gone round the ring many times.
  • The jam drives backwards, at about 6 km/h in your Step 2, while every car in it drives forwards.
  • There is a sharp line. With 10 cars or fewer the jam always died; with 13 or more it never did.
  • A jam is expensive. Sixteen cruising cars carried 48 cars a minute; after one brake, 19.

This is the answer to the question. A jam needs no accident and no bottleneck, only enough cars and drivers who are a little slow to get going again. Below the line, the road heals itself. Above it, the smooth flow is like a pencil standing on its point: it can last, but any small push (one driver braking, a bus pulling in, someone changing lanes) knocks it over, and it doesn’t stand up again by itself. What you saw from the bus was the back of a jam whose cause was long gone, perhaps minutes ago and kilometers ahead.

Going further still

Perfect drivers

In traffic.py, make P = 0 and run Step 3. Every jam dies, with 16 cars as with 8: with 14 cars, everyone is cruising again 12 seconds after the brake. Without the dawdle, the drivers leave the front of a jam as fast as the cars arrive at the back. The jam lives on drivers being a little slow.

The 1992 model: everyone dawdles

Nagel and Schreckenberg’s first model let every car dawdle, even one cruising on an empty road. In step, change the line if not (v == VMAX and gap == VMAX): to if True:, and run Step 2 without the brake (take out road[0] = 0). With 14 cars a stopped car appears within half a minute, and jams come and go by themselves: jams truly out of nowhere. With 5 or 8 cars, nobody stops in those two minutes.

Two lanes, and a junction

Make the road two lists side by side and add a rule for changing lanes: if the lane beside you has more room ahead, move across. Or cut the ring open into a straight road, add a car at the start each second with some chance, and take cars off at the end. Does a lane change start a jam? Where do the jams form on the open road?

An open question

Real jams keep a nearly constant speed backwards, about 15 km/h, and a nearly constant flow of cars out of their fronts, which any good model must explain. But how does real traffic change from smooth to jammed? Boris Kerner, from measurements on real motorways, argues for three kinds of traffic, not two: free flow, wide moving jams like this topic’s, and in between a “synchronized flow”, slow but moving, in every lane at once. Researchers still argue about it, and about which models describe real roads best.

Challenges

Three challenges, each checked on the page: write your function in the program above the checker (press Edit), then press Check my program. The examples show what your function should give; there are more tests you can’t see.

★ Room ahead

gap_ahead looked at most 5 cells ahead. Write empty_ahead(road, i): the number of empty cells in front of the car in cell i however many there are, going round the ring. If it is the only car, every other cell is empty.

def empty_ahead(road, i):    # Give back how many empty cells there are in front of the car in cell i.    return 0 print(empty_ahead([5, None, None, 0, None], 0))

Try it

★ Room ahead

  1. The example empty_ahead([5, None, None, 0, None], 0) Should give 2 Yours —
  2. Round the end of the ring empty_ahead([5, None, None, 0, None], 3) Should give 1 Yours —
Tests passed
— / 8
Challenge
★ solved

Write your empty_ahead in the program above (Edit), then check it.

A test your function gets wrong, anything it prints, and any error appear here.

Hint
Answer

★★ Perfect drivers

Write perfect_step(road): the road one second later when nobody dawdles. Every car speeds up by 1 (to at most 5), slows to the empty cells ahead, and moves, all at once, on a ring.

def perfect_step(road):    # Give back the road one step later, with drivers who never dawdle.    return road print(perfect_step([5, None, None, None, None, None, None, 0, None, None]))

Try it

★★ Perfect drivers

  1. The example perfect_step([5, None, None, None, None, None, None, 0, None, None]) Should give [None, None, None, None, None, 5, None, None, 1, None] Yours —
  2. Two cars cruising perfect_step([5, None, None, None, None, None, 5, None, None, None, None, None]) Should give [None, None, None, None, None, 5, None, None, None, None, None, 5] Yours —
Tests passed
— / 8
Challenge
★★ solved

Write your perfect_step in the program above (Edit), then check it.

A test your function gets wrong, anything it prints, and any error appear here.

Hint
Another hint
Answer

★★★ How far back does it reach?

With perfect drivers, write slowed(road, steps): run the road for steps steps with the rules from ★★ and give back, for each car, how many steps it ended below top speed. List the cars in order of the cell they started in, from cell 0 up. The cars move round the ring, so you need a way to know which car is which.

def slowed(road, steps):    # Give back how many steps each car ended below top speed, in order of their starting cells.    return [] road = [None] * 100for k in range(16):    road[k * 100 // 16] = 5        # 16 cars, all at top speedroad[0] = 0                        # the car in cell 0 brakesprint(slowed(road, 100))

Try it

★★★ How far back does it reach?

  1. Sixteen cars, one brake slowed([0, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, 5, None, None, None, None, None, None], 100) Should give [4, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] Yours —
  2. Eight cars, one brake slowed([0, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, None], 100) Should give [4, 0, 0, 0, 0, 0, 0, 2] Yours —
Tests passed
— / 8
Challenge
★★★ solved

Write your slowed in the program above (Edit), then check it.

A test your function gets wrong, anything it prints, and any error appear here.

Hint
Another hint
Answer

Questions

In the model, why does a jam move backwards when every car in it moves forwards?

Pick an answer to see why.

Your Step 3 braked one car on rings with different numbers of cars. What did it find?

Pick an answer to see why.

a.

On a ring of 16 cars with no brake, your Step 4 found 48 cars a minute; with one brake, 19. Explain why one second of braking can cost the road over half its traffic for good.

Answer
b.

With Drivers: Perfect (no dawdling), a jam on the ring clears within about 20 seconds, even with 16 cars. What does this suggest about what really causes phantom jams, and about how cars that drive themselves might help?

Answer
c.

Your Step 2 measured the model’s jam moving backwards at about 6 km/h; real jams move back at about 15 km/h. Which rule of the model would you change to make its jams move faster, and in which direction? Try it.

Answer
d.

A traffic police officer says: “There’s a jam on the highway every evening at the same place, but there’s no junction or narrowing there. Someone must be stopping.” Use this topic to give another explanation.

Answer

Where to go next