Nagel-Schreckenbergモデル
信号も事故も合流もない、ただの環状一車線。それでも密度がある値を超えると、 誰ひとりブレーキを踏む理由がないのに渋滞が自然に発生する。 しかも渋滞の塊はその場に留まらず、車の進行方向とは逆向きに、後方へ伝播していく。 条件はひとつだけ、ドライバーがときどき理由もなく減速すること。
環状道路を一直線に展開したもの(右端と左端はつながっている)。色は各車の速度。
時空図 — 横軸が位置、縦軸が時間で、1ステップごとに1行ずつ下に積もっていく。 1本の斜め線が1台の車の軌跡。左下がりの濃い縞が渋滞の塊で、 車が右へ進んでいるのに縞は左へ流れる。これが渋滞の後方伝播。
p を 0 にしてみる。最初の乱れがほどけたあとは、 どれだけ待っても渋滞が生まれなくなる。ゆらぎこそが渋滞の源であることが、これで分かる。
基本図
密度を変えながら、そのときの流量(単位時間に通過する台数)を測ったもの。 低密度では車が増えるほど流量も増えるが、ある臨界密度でピークを打ち、 そこから先は渋滞相に入って流量が落ちる。この山形が交通工学でいう基本図そのもの。 p を変えて描き直すと、山の高さと頂点の位置がどう動くかが見える。
アルゴリズムと実装
Kai Nagel と Michael Schreckenberg が1992年に発表したモデル。 規則は4つしかないのに、実測の交通流に現れる性質をひととおり再現してしまう。
盤面
- 長さ L の1次元セル配列。各セルは空か、車がちょうど1台。
- 各車は整数の速度 v(0以上 vmax 以下)を持つ。速度は「1ステップで進むセル数」。
- 端は周期境界。右端の次は左端で、要するに環状道路。 こうすると車の総数が一定に保たれ、密度を固定したまま定常状態を観察できる。
1ステップの4段階
全車について、段階ごとにまとめて処理する。順番が意味を持つ。
- 加速 —
v ← min(v + 1, vmax)。誰もが機会があれば速く走りたい。 - 減速 —
v ← min(v, gap)。gap は前の車との間の空きセル数。 追突しないための制約で、これがあるので車が詰まると速度が落ちる。 - ゆらぎ — 確率 p で
v ← max(v - 1, 0)。理由のない減速。 - 移動 —
x ← (x + v) mod L。
同期更新でなければならない理由
4段階は全車について同時に進める。 1台ずつ「加速して減速してゆらいで移動」まで済ませてから次の車に移る、という書き方をしてはいけない。
非同期にすると、後ろの車が gap を測る時点で前の車が既に動いてしまっている。 つまり前の車の動きを先読みしたことになり、追突の危険が消えて車間が詰まる。 渋滞は「前が動いたことを後ろがまだ知らない」という情報の遅れから生まれるので、 それを消してしまうとモデルの核心が失われる。 Schellingの分居モデルが非同期更新だったのとは対照的で、 同じセルオートマトンでも更新規則の選択がモデルの意味そのものを決める。
gap の計算と環状配列
車を環状の並び順のまま配列に持ち、i 番目の車の前方の空きセル数を次式で求める。
gap = (pos[i+1] - pos[i] + L) % L - 1
剰余を挟むことで、配列の切れ目をまたぐ車(右端から左端へ回り込んだ車)も特別扱いせずに済む。 速度が gap 以下に抑えられる以上追い越しは起こり得ないので、 配列上の並び順は最初から最後まで環状順のまま保たれる。並べ替えは一度も要らない。
ゆらぎ p が渋滞の源
p = 0 だと、均質な初期配置からは渋滞が生まれない。 全員が同じ規則で決定論的に動くので、車間が揃った状態に落ち着いてそのまま続く。
p > 0 にすると話が変わる。1台がたまたま減速すると、その後ろの車は gap が縮んで減速を強いられ、 さらにその後ろも減速する。この連鎖が後ろへ後ろへと遡っていく。 一方で先頭の車は前が空いているので加速して抜けていく。 結果として、塊そのものは車と逆向きに移動する。時空図の左下がりの縞がそれ。
流量の測り方
流量 q は「単位時間に断面を通過する台数」で、密度 ρ と平均速度 v̄ の積 q = ρ · v̄。
実装では全車の速度の総和を道路長で割るだけでよい(q = Σv / L)。
1ステップで車 i は v_i セル進むので、その総和が全体の移動量になり、L で割ると1セルあたりの通過台数になる。
基本図の測り方
- 密度を 0.01 から 0.90 まで 0.01 刻み、計90点。
- 各点で新規初期化したあと、まず500ステップ空回しする。 初期配置はランダムなので、そのままでは初期条件の名残(過渡状態)を測ってしまう。これを捨てる。
- 続く500ステップで
Σv / Lを毎ステップ足し込み、平均したものを流量として記録する。 - 90点×1000ステップと重いので、2点ごとに制御をイベントループへ返して画面が固まらないようにしている。
時空図の描き方
1ステップ=1行。新しい行を下端に描き、次のステップではキャンバス全体を1行ぶん上へずらす。
ずらすのは drawImage でキャンバス自身を1行上に描き直すだけ(合成モードを
copy にして、はみ出した下端が透明で残るようにしている)。
履歴用のバッファを別に持つ必要がない。
縞の傾きが渋滞の伝播速度そのもので、符号は負、つまり後方へ伝わる。
速度は基本図の渋滞側の傾き dq/dρ として読める。
既定値 p = 0.30 では1ステップあたり約 マイナス0.58セルで、
p を上げるほど絶対値は小さくなる(p = 0.5 で約 -0.38、逆に p = 0 では厳密に -1)。
このモデルの標準的な換算は1セル = 7.5m、1ステップ = 1秒。 これを当てはめると -0.58セル/ステップは時速およそ15km で上流へということになる。 実際の高速道路で渋滞の先頭が時速15km前後で後方へ動くことは古くから観測されていて、 4行の規則からその値が出てくる。
配色について
速度は順序のある量なので、色は単一色相の明度ランプで表している (明るいほど遅く、暗いほど速い)。赤〜青の虹色ランプは一見わかりやすいが、 中間の速度どうしの明度差がほとんど無くなり、速度3と速度4が区別できなくなる。 色に頼らずに済むよう、凡例で速度と色の対応を明示している。