← Past problems · 2015 set

2015 · Problem A — Preventing Road Rage

Traffic flow Agent-based simulation Cellular automata Behavioral modeling

Read the official PDF →

The prompt, restated

Highway construction routinely forces a two-lane road down to one lane. Drivers respond in two dominant ways: an "efficient" late merge (use both lanes all the way to the closure cone, then zipper one-for-one), or an "early merge" in which drivers move to the open lane as soon as the sign appears and the closing lane runs largely empty. The latter feels fair to many drivers and explains the road-rage outbursts at late mergers who appear to "cut in line." The prompt asks: which behavior is actually better, and by what measure?

Specifically, teams are asked to (1) build a mathematical model that captures the two behaviors and compares them on throughput, total delay, and a fairness measure of the team's choice; (2) extend the model to a three-lane-to-one closure, where the merge structure is no longer symmetric; (3) compare highway behavior to the analogous problem on a lower-speed secondary road, where signal timing, sight distance, and driver mix differ; and (4) translate the model into actionable outputs — guidelines for a driver-education pamphlet and a recommendation to a state Department of Transportation on what signs to post and where. A short non-technical summary is required.

Key modeling idea

Treat the closure as a capacity bottleneck: upstream demand $q_{\text{in}}$ versus single-lane downstream capacity $C \approx 1800$ veh/h. When $q_{\text{in}} > C$ a queue forms, and the merging policy determines (a) how much of the upstream road is used to store that queue and (b) how often vehicles must stop, which drives both delay and the road-rage signal. The cleanest model is a cellular-automata (Nagel–Schreckenberg) simulation with a merge rule layered on top — late-merge agents stay in their lane until the cone, early-merge agents change lanes as soon as they see the warning sign.

Suggested approach

  • Step 1 — Pick the simulator. Use Nagel–Schreckenberg: 1D cell grid, cell length 7.5 m, time step 1 s, max speed 5 cells (≈135 km/h). Update rule = accelerate, brake if leader close, randomize with probability $p$, then move. This reproduces the fundamental diagram (flow-vs-density curve) of real traffic well enough for HiMCM.
  • Step 2 — Add the merge rule. For a 2→1 closure: each car in the closing lane samples a "merge willingness" distance $d^* \sim \mathcal{N}(\mu, \sigma)$ from the cone. Late mergers have $\mu \approx 50$ m, early mergers $\mu \approx 800$ m. A car merges the first time the gap in the open lane exceeds a safe threshold ($\approx 2$ s headway).
  • Step 3 — Sweep demand. Run each policy across $q_{\text{in}}$ from 600 to 2400 veh/h and tabulate average travel time, throughput, and number of "forced stops" per vehicle (a proxy for road-rage trigger events). Expect late merge to win on throughput at high demand by 10–20% [illustrative], and the gap to vanish below capacity.
  • Step 4 — Extend to 3→1. The fair analog is a two-stage zipper: lane-3 to lane-2, then lane-2 to lane-1. Show that signage placing the two cone tapers ~300 m apart outperforms a single tri-merge point.
  • Step 5 — Secondary roads. Lower free-flow speed (50 km/h), lower capacity (~900 veh/h/lane), more cross-traffic. The qualitative story flips: early merging is closer to optimal because queue storage is cheap and the speed differential between lanes is small.

Data sources to consider

SourceWhat you get
FHWA Highway Capacity ManualPer-lane capacity, free-flow speed, work-zone capacity reduction factors
MUTCD (Manual on Uniform Traffic Control Devices)Standard work-zone signage, taper lengths, advance-warning distances
Minnesota DOT & PennDOT "zipper merge" campaignsReal-world before/after data on late-merge signage; throughput gains 15% [illustrative]
NGSIM trajectory datasetVehicle-by-vehicle position/speed traces; useful for calibrating headway distributions
NHTSA aggressive-driving / road-rage reportsSelf-reported triggers; ties the "forced stop" metric to a real outcome

Common pitfalls

  • No definition of fairness. Teams declare zipper "fair" without saying what the word means. Pick one — equal expected delay across lanes, or low variance in individual delay — and defend it.
  • Throughput as the only metric. Road rage is about perceived unfairness. Report at least one behavioral metric (forced stops, headway violations, lane-change attempts per vehicle) alongside flow.
  • Ignoring queue storage. Early merge piles a long queue in one lane that can spill back past an upstream interchange and trigger a secondary jam. Late merge spreads the queue across both lanes.
  • One scenario only. Judges want a demand sweep. A model that works at 1200 veh/h but flips at 2000 veh/h needs to say so.
  • Forgetting the deliverables. The prompt explicitly asks for a driver-education pamphlet and a DOT signage recommendation. A great paper packages those as appendices.

Python sketch

Minimal Nagel–Schreckenberg with a late-vs-early merge rule.

import numpy as np

L, vmax, p_brake = 800, 5, 0.2          # 800 cells = 6 km road, 1 cell = 7.5 m
cone = 700                              # cone at cell 700 (lane-2 closes)
rng  = np.random.default_rng(0)

def step(lane1, lane2, policy="late"):
    # accelerate, brake, randomize, move — per lane
    for lane in (lane1, lane2):
        v = lane["v"]; x = lane["x"]
        v = np.minimum(v + 1, vmax)
        order = np.argsort(x)
        for k in order:                                  # gap-aware brake
            ahead = x[(order[(np.where(order==k)[0][0]+1) % len(order)])] - x[k]
            v[k] = min(v[k], max(0, ahead - 1))
        v[rng.random(len(v)) < p_brake] = np.maximum(v[rng.random(len(v)) < p_brake]-1, 0)
        lane["x"] = (x + v) % L; lane["v"] = v
    # merge rule on lane-2 cars
    d_star = 50 if policy == "late" else 800
    keep = lane2["x"] < (cone - d_star)
    movers_x = lane2["x"][~keep]
    # accept into lane-1 if 2-sec gap exists
    for px in movers_x:
        gaps = np.abs(lane1["x"] - px)
        if gaps.min() > 2 * vmax:
            lane1["x"] = np.append(lane1["x"], px); lane1["v"] = np.append(lane1["v"], 2)
    lane2["x"] = lane2["x"][keep]; lane2["v"] = lane2["v"][keep]
    return lane1, lane2

# run two policies, compare throughput past cone over 3600 s
# (full driver init + metric collection omitted for brevity)

Sensitivity & validation checklist

  • Sweep $q_{\text{in}}$ from 0.4 C to 1.4 C and plot delay vs. policy. The crossover demand is your headline result.
  • Vary the merge-willingness distribution $(\mu, \sigma)$ to model real driver heterogeneity — pure-policy worlds are unrealistic.
  • Test signage placement: move the advance-warning sign from 200 m to 2 km upstream and rerun. The "Use Both Lanes" message effectively shifts $\mu$.
  • Compare simulated flow against the empirical fundamental diagram (NGSIM) — your model should produce ~2000 veh/h/lane at the critical density.
  • Inject a stalled vehicle as a stress test. Late merge degrades gracefully; early merge can deadlock if the open lane is already saturated.

Related pages