matsulibの日記

Ingredients as Code

pygameによる避難シミュレーションとその動画

障害物効果

 避難において出入口付近に障害物を置くと逆に流れがスムーズになる場合がある。この障害物効果はもともと計算機シミュレーションによって発見されたもので、現実にも応用されているらしい。

pygame

 障害物効果を自分でも試したくて、障害物の場所をマウスでポチポチと指定できるゲームを作ろうと思った。格子状に配置されたセル上を各エージェントが避難口に向かって移動するモデルをフロアフィールド(FF)モデルといい、その格子とゲームのレイアウトはこのサイトを参考にした。
Writing a game in Python with Pygame. Part III - Eli Bendersky's website

行動ルール

 エージェントの行動ルールは参考文献[1]の論文を参考にした。エージェントと言っても避難してる人は協力もしなければ学習もしない、まともな意思決定をしないと仮定すれば、分子運動(ただしランダムではなく避難口に向かう)と同様にモデル化できる(?)。ここで唯一存在する相互作用は「衝突」で、これは移動がキャンセルされるだけなのでプログラムではわざわざエージェントクラスは作らず、エージェントたちはただの座標のリストとして実装できた。しかし…

論文の結果を再現できない…

 コーディングがどこかで間違っているのだろうか。避難口の手前で団子のような行列ができてしまうのだが、でもこれは論文で与えている行動ルールからすれば妥当だと思える(避難口方向への移動確率が強すぎる)。それにこの設定では衝突確率が低いので、そもそも障害物なんて無い方がマシ。障害物が直感通りの邪魔にしかならず、障害物効果が再現されない。

都合の良い結果

 仕方がないので行動ルールとパラメータを弄って、障害物効果が再現出来た例を挙げる。変更点は二つ。
・衝突確率を上げる
・避難口方向が既に他のエージェントや障害物で埋まっていた場合、他の方向に移動確率を割り振る
 
 出口の方に向かうという単純な行動ルールのせいで最後の方で障害物に引っかかる奴がいるため、全300人のうち290人が避難完了した時点でのステップ数、出口での衝突回数、流動係数(空間の単位幅あたり、単位時間に何人の人が通過できるかに用いる指標→大きい方が良い)を表示する。

f:id:matsulib:20131125183252p:plain:w450f:id:matsulib:20131125183307p:plain:w450f:id:matsulib:20131125183321p:plain:w450f:id:matsulib:20131125183341p:plain:w450f:id:matsulib:20131125183356p:plain:w450f:id:matsulib:20131125183408p:plain:w450f:id:matsulib:20131125183423p:plain:w450

 この配置だと障害物効果が確認できる。3人より2人の方が衝突確率が低いという設定だから当然といえば当然か。出口手前の3セル以外の場所に障害物を置いて流動係数が上がる例も論文にはあるけど、手元のシミュレーションでは全部ただの邪魔になる。

動画化

 pygameで毎回画面を描写するついでに pygame.image.save('out.png') という関数を呼べばその画面を画像として保存できる。動画をそのまま出力する機能はないようだ。上の画像は二回のシミュレーション結果をそれぞれ連番pngファイルとして保存して、Python Imaging Library (PIL)で対応する画像同士を結合させたもの。
 これのアニメーション化は以前も登場した皆大好きffmpegで、バッチファイルではこう書けば出来た。

ffmpeg -r 15 -i out^%%05d.png -qscale 0 out.avi

 ^%%0とかの挙動はOSやバッチファイルかコマンドプロンプトかによって変わるらしく意味不明なので別の方法使うなり適当にやって下さい。
バッチ・モードでのターミナルの使用法


 Youtubeに上げたかったけど捨て垢作るのが凄く面倒になってたのでニコ動。

 まあいかにも微妙だし、これを研究室で紹介したらすこぶる評判が悪かった…

参考文献

[1]谷本潤, 萩島理, and 田中尉貴. "避難口のボトルネック効果に関するマルチエージェントシミュレーションと平均場近似に基づく解析." 日本建築学会環境系論文集 74.640 (2009): 753-757.