The city is a street grid graph. Every node runs a single multi-source Dijkstra search seeded from the four gate nodes, giving every intersection a shortest travel-time route out of the city — this is recomputed on a fixed interval while adaptive routing is on, so agents reroute the moment a road gets congested or closed.
Each street segment's travel time follows a BPR-style congestion function:
t(load) = t0 · (1 + α·(load/capacity)²)
where t0 is the free-flow time, load is how many agents are currently on that segment, and capacity is its safe throughput. As α rises, jammed streets get punished harder in the routing search, so agents peel off onto side streets sooner.
- Adaptive OFF — routes are computed once from free-flow times and never updated: agents pile up on the "fastest" street even after it jams, a naive-routing baseline.
- Close corridor — blocks the central avenue's north–south segments (a collapsed road), forcing a live reroute around it while adaptive is on.