Traffic Flow Modelling & Reinforcement Learning via the LWR Conservation Law and Godunov Schemes
1. Macroscopic Conservation Law & Greenshields Closure
Let $\rho(x,t) \in [0, \rho_{\max}]$ denote spatial vehicle density (veh/m) and $q(x,t)$ denote macroscopic flow rate (veh/s) along a road link $x \in [0, L]$. Conservation of vehicles over any control volume $[x_1, x_2]$ requires $\frac{d}{dt}\int_{x_1}^{x_2} \rho(x,t)\,dx = q(x_1,t) - q(x_2,t)$, yielding the scalar hyperbolic PDE:
where $v_f > 0$ is the free-flow speed and $\rho_{\max} > 0$ is the jam density. Because $q''(\rho) = -2v_f / \rho_{\max} < 0$, the flux function $q(\rho)$ is strictly concave and attains its unique capacity maximum $q_{\max} = \frac{1}{4} v_f \rho_{\max}$ at the critical density $\rho_c = \frac{1}{2}\rho_{\max}$.
2. Method of Characteristics, Shockwaves & Rarefaction Fans
For smooth solutions, the chain rule gives the quasi-linear advection equation $\partial_t \rho + c(\rho)\partial_x \rho = 0$ with kinematic wave speed:
3. Conservative Godunov Demand–Supply Scheme
Partitioning each road link into $N$ finite-volume cells $C_i = [x_{i-1/2}, x_{i+1/2}]$ of width $\Delta x = L/N$, cell averages $\rho_i^n$ evolve via the exact conservation update:
Splitting $q(\rho)$ at the critical density $\rho_c$ defines upstream kinematic Demand $D(\rho)$ and downstream Supply $S(\rho)$:
Python Implementation — Vectorised Godunov Demand–Supply Solver [Show / Hide Code]
import numpy as np
def demand(rho: np.ndarray, vf: float, rho_max: float) -> np.ndarray:
rho_c = 0.5 * rho_max
q_max = 0.25 * vf * rho_max
q = vf * rho * (1.0 - rho / rho_max)
return np.where(rho <= rho_c, q, q_max)
def supply(rho: np.ndarray, vf: float, rho_max: float) -> np.ndarray:
rho_c = 0.5 * rho_max
q_max = 0.25 * vf * rho_max
q = vf * rho * (1.0 - rho / rho_max)
return np.where(rho <= rho_c, q_max, q)
def godunov_step(rho: np.ndarray, dx: float, dt: float, vf: float, rho_max: float,
q_in: float, s_out: float) -> np.ndarray:
d = demand(rho, vf, rho_max)
s = supply(rho, vf, rho_max)
flux = np.empty(len(rho) + 1)
flux[0] = min(q_in, s[0])
flux[1:-1] = np.minimum(d[:-1], s[1:])
flux[-1] = min(d[-1], s_out)
return rho + (dt / dx) * (flux[:-1] - flux[1:])
4. Shared-Table Q-Learning, Sensor Priors & Multi-Agent Scaling
Across signalised grids of 1 to 36 junctions ($1\times 1$ to $6\times 6$), independent tabular controllers would suffer exponential joint state-space growth ($96^{36}$). Instead, all junctions share a single Q-table $Q(s, a)$ over a compressed 96-state phase-relative representation:
The controller is trained on network-wide flux rewards and initialised with sensor-informed priors to accelerate cold-start convergence. Benchmarked against both sensor-actuated and fixed-time control over 6 held-out demand seeds per load:
| Grid Size | Junctions | Medium Load TTS vs Actuated | Heavy Load TTS vs Actuated | Peak Junction Flux Gain |
|---|---|---|---|---|
| 1×1 | 1 | −7.5% | +9.5% | +0.8% |
| 2×2 | 4 | −10.3% | −15.8% | +1.7% |
| 3×3 | 9 | −15.4% | −10.2% | +2.2% |
| 4×4 | 16 | −19.4% | −17.0% | +2.9% |
| 6×6 | 36 | −16.4% | −17.0% | +2.6% |
Scaling & Multi-Agent Constraints: The efficiency gain of the RL system over baseline methods scales positively with network size and complexity—cutting total time spent by 7–19% at medium load on grids of $2\times 2$ and up, and raising junction flux by up to 2.9%—while identifying partial observability and multi-agent credit assignment as constraints on multi-agent scaling.