Nagel-Schreckenbergモデル

信号も事故も合流もない、ただの環状一車線。それでも密度がある値を超えると、 誰ひとりブレーキを踏む理由がないのに渋滞が自然に発生する。 しかも渋滞の塊はその場に留まらず、車の進行方向とは逆向きに、後方へ伝播していく。 条件はひとつだけ、ドライバーがときどき理由もなく減速すること。

環状道路を一直線に展開したもの(右端と左端はつながっている)。色は各車の速度。

時空図 — 横軸が位置、縦軸が時間で、1ステップごとに1行ずつ下に積もっていく。 1本の斜め線が1台の車の軌跡。左下がりの濃い縞が渋滞の塊で、 車が右へ進んでいるのに縞は左へ流れる。これが渋滞の後方伝播。

平均速度
流量
ステップ0
停止車両

p を 0 にしてみる。最初の乱れがほどけたあとは、 どれだけ待っても渋滞が生まれなくなる。ゆらぎこそが渋滞の源であることが、これで分かる。

基本図

密度を変えながら、そのときの流量(単位時間に通過する台数)を測ったもの。 低密度では車が増えるほど流量も増えるが、ある臨界密度でピークを打ち、 そこから先は渋滞相に入って流量が落ちる。この山形が交通工学でいう基本図そのもの。 p を変えて描き直すと、山の高さと頂点の位置がどう動くかが見える。

未実行

アルゴリズムと実装

Kai Nagel と Michael Schreckenberg が1992年に発表したモデル。 規則は4つしかないのに、実測の交通流に現れる性質をひととおり再現してしまう。

盤面

  • 長さ L の1次元セル配列。各セルは空か、車がちょうど1台。
  • 各車は整数の速度 v(0以上 vmax 以下)を持つ。速度は「1ステップで進むセル数」。
  • 端は周期境界。右端の次は左端で、要するに環状道路。 こうすると車の総数が一定に保たれ、密度を固定したまま定常状態を観察できる。

1ステップの4段階

全車について、段階ごとにまとめて処理する。順番が意味を持つ。

  1. 加速v ← min(v + 1, vmax)。誰もが機会があれば速く走りたい。
  2. 減速v ← min(v, gap)。gap は前の車との間の空きセル数。 追突しないための制約で、これがあるので車が詰まると速度が落ちる。
  3. ゆらぎ — 確率 p で v ← max(v - 1, 0)。理由のない減速。
  4. 移動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が区別できなくなる。 色に頼らずに済むよう、凡例で速度と色の対応を明示している。