メディア

MATSim実践編――渋滞をシミュレーションしてみる:リタイア直前エンジニアの社会人大学漂流記(8-2)(2/4 ページ)

» 2026年10月26日 13時30分 公開
[江端智一,EE Times Japan]

QSimとは何か

 では、QSimをざっくりご説明したいと思います ―― いつものことですが、あなたに理解してもらうというより、この私がQSimを理解することを目的として、私が私のために実験用プログラムを書き、図面を作成します。これまでのコラムの通り「私が理解できさえすればOK」を、今回も押し通します。

 プログラムはGo言語で作成します ―― 私のオリジナルのMASのシミュレータ(EBASim)がGo言語で作成されており、この連載の執筆後に、この検証プログラムを EBASim に組み込むという魂胆(こんたん)のためです。

 QSimは、エージェント(人や車)が、交通ネットワークを移動する様子をシミュレーションするものです。まず、この説明に入る前に用語を整理します。

[クリックで拡大]

 今回扱う範囲では、QSimの交通ネットワークは、つまるところ4つの要素を押さえておけば十分なようです。それぞれの要素については以下の図で説明します。

[クリックで拡大]

 NodeとLinkが道路ネットワークを構成し、Agentが人や車両、Route は経路(Link の順番の列)という理解で十分です。

 なお、以下では正式なモデル要素を「Link」と呼びますが、その振る舞いを直感的に説明するため、車両の動きについては「トンネル」、流量や容量については「ホース」に例えることがあります。

 さて、今回の実験的なシミュレーションにおける、エージェントの移動プロセスは、以下の通りです。

[クリックで拡大]

 まあ、当たり前のことを書いているだけですが、今回はエージェントの移動ルートはあらかじめ決定しており、移動中の変化とかは「ない」ものとします ―― 渋滞で嫌になって帰宅したりする、ということは「ない」ということです。

 で、今回の検証用プログラムでは、QSimの振る舞いを「時間刻みでエージェントの移動を更新するもの」として実装します。今回は、各Linkのキュー(列)やNodeの通過状態を更新し、Linkの容量制約や、Nodeにおける通過ルールに基づき、エージェントの移動を1秒ごとに変えていく、という方式とします。

 で、最終的に、シミュレーションから得られる交通量やキュー長が、理論的に予想される値と一致するかどうかを確認し、この検証プログラムの妥当性を確認するものとします。

 では、次にLink内部の振る舞いの説明をします。

[クリックで拡大]

 言っていることは簡単です。トンネルに入り、しばらくは快調に走っていたものの、出口付近で渋滞が発生し、そこで待たされた後にトンネルの外へ出る、というイメージです。

 ところが、これ、事前に考えなければならないことがいくつかあるのです。NodeとNodeの間をトンネルと考えると分かりやすいのですが、トンネルには、(1)有限の長さ、(2)有限の車線数、そして(3)制限速度があります。従って、収容できる車両数や、単位時間あたりに通過できる車両数にも上限があります。

[クリックで拡大]

 ここからは、特に流量や容量を考えるために、Linkを「水が流れるホース」に例えてみます。

[クリックで拡大]

 さらに、(4)storage capacityは、ホースそのものが内部に保持できる最大の水量、(5)spillbackは、ホース内部が満杯になり、さらに上流から水を入れられなくなる状態、と考えればよいでしょう。

[クリックで拡大]

 上記の図は、1時間に1800台までしか流出できないLinkに、1時間あたり2200台の車両が流入するとどうなるか、ということを表しています。当然のことながらトンネル内部で渋滞が発生し、その渋滞はいずれトンネルの外にも及ぶことになります。

[クリックで拡大]

 上図は、これを簡単に説明したものです。Linkの中が車で一杯になれば、そのLinkには新たな車両が入り込めなくなります。すると、上流側のLinkにいる車両はそこで待たされることになります。



 さて、ここまで整理したところで、今回作成するプログラムのアルゴリズムについて説明します。

 以下は、1秒刻みの更新手順であるシミュレーションループを示す図です。今回の検証プログラムでは、全エージェントを同じシミュレーション時刻にそろえ、決めた手順で処理することで、交通流の整合性を保ちます。

[クリックで拡大]

 この図では、シミュレーション時刻 t における全エージェントの状態を確認した後、それぞれのエージェントについてLink内の移動、Nodeでの通過判定、Linkのflow capacity/storage capacityの確認、到着処理を順番に行います。そして、全ての処理が終わったら時刻を t+1 秒に進め、同じ処理を繰り返します。

 つまり、

「全エージェントを1秒分だけ動かす → 道路容量やNode通過の制約を反映する → 時刻を1秒進める」

という処理を、シミュレーション終了時刻まで繰り返すだけです。

 今回の検証プログラムでは、この単純なループの中で、free-flow travel time、flow capacity、storage capacity、FIFO、spillbackといったQSimの基本的な振る舞いを再現していきます。



 ここで、今回のGoプログラムで使っている時刻同期(barrier)について簡単に説明します。時刻同期とは、複数のエージェントを並行に扱っても、全エージェントが現在時刻 t の処理を終えるまで、誰も次の時刻 t+1 の処理に進ませない仕組みのことです。

[クリックで拡大]

 つまり、全エージェントの時刻をそろえるために、時刻tの処理を終える前に、別のエージェントが時刻t+1の処理を始めない、ということです。今回のプログラムでは、Go言語で1つのエージェントに1つのgoroutineを割り当てているのですが、このような時刻同期型の処理を実現するだけであれば、エージェントごとにgoroutineを割り当てる必要はありません*)。

*)私のEBASimへの適用を前提として、そのように実装しているだけです。

 この時刻同期により、あるエージェントだけが他のエージェントより先に次の時刻へ進むといった、時間的な不整合を防ぐことができます(で、実は、この「全員の時刻をそろえる」という考え方こそが、EBASimにおいて決定的に困る点でもあるのですが、この話はいずれまたの機会に)。

 このシミュレーションによって、次のようなものが出てきます。

[クリックで拡大]

 この図では、シミュレーションの進行に伴って得られる代表的な指標を示しています。

  • 左図は、平均旅行時間、平均待ち行列長、ネットワーク内車両数などが、時間とともにどのように変化するかを示した時系列データです。
  • 右図は、それらを集計したもので、平均・分布としての旅行時間、各Linkの待ち行列長、目的地への到着台数、各時刻のネットワーク内車両数などを確認できます。
  • その他、遅れ時間、リンク通過時間、速度、停車回数などを出すことも可能です。

 つまり、このQSimシミュレーションによって、「いつ、どこで、どの程度混雑し、その結果として車両の移動にどのような影響が出たか」を、時間変化と集計値の両方から評価できるわけです。

 ここまでのQSimシミュレーションの内容をまとめてみましょう。

[クリックで拡大]

 今回扱うQSimの基本的なqueue型の振る舞いを単純化すると、QSimは、時間刻み、FIFO、容量制約、時刻同期によって交通流を表現する仕組みと捉えることができます。エージェント全員の移動を扱うMATSimの中で、QSimはミクロ交通流シミュレーションのような詳細な位置情報(何時何分何秒に、メートル単位でどこにいたか)までは追跡しないものの、その時刻に、各エージェントがどのLink上にいたかは、きちんと把握できます。

 つまり ―― 「江端(の自動車)は8時03分12.3秒にLink-17の入口から357.2m地点を時速42.6kmで走っていた」ということは分からないですが、「江端(の自動車)は、8時03分12秒にLink-17にいて、次にLink-24へ移動した」ということはバッチリ分かる ――ということです。

 これが、 個々のエージェントは追跡するが、その細かな車両運動までは追跡しない、「ミクロとマクロの中間(メソ)」に位置するMATSimの大きな強みなのです。

Copyright © ITmedia, Inc. All Rights Reserved.

特別協賛PR
スポンサーからのお知らせPR
Pickup ContentsPR
Special SitePR
あなたにおすすめの記事PR

RSSフィード

公式SNS

All material on this site Copyright © ITmedia, Inc. All Rights Reserved.
This site contains articles under license from AspenCore LLC.