理系的な戯れ

理工学系とくにロボットやドローンに関する計算・プログラミング等の話題を扱って、そのようなことに興味がある人たちのお役に立てればと思っております。

Pythonでワシントンポストのコロナシミュレーションを再現してみた

f:id:kouhei_ito:20200323200254p:plain

はじめに

こんにちは、こうへいです。

今日は、コロナウイルスの伝搬状況を ワシントンポストがシミュレーションしていまして それが面白かったので、自分でも書いてみたいと思って、コーディングの練習も兼ねて挑戦したお話です。

シミュレーションの概要

WPのシミュレーションは人に見立てた粒子がランダムに行動する場合に濃厚接触すると 感染が広がっていくことを模擬していました。

粒子の動きが緩慢な場合や、閉じ込められていた粒子が広い空間に解き放たれた場合など、数種類のケースが 比較されていて面白いものです。

狭い範囲に多くの粒子があり、それらの粒子が活発に活動している時が最も感染の広がりの速度が速く、一度広がりだすと指数関数的に増えていきます。

感染した粒子は一定の時間が経つと治癒して、それ以上は感染しなくなるといったシミュレーションでした。

シミュレーションをPythonで再現

では、自前で再現してみた結果を以下に示します。

全ての計算で粒子数は100です。計算ステップ数は150回です。 どの計算でも、最初の感染者は活発に移動するものとしています。

全ての粒子が活発に活動する場合

すべての粒子が活発に活動する様に設定しています。

f:id:kouhei_ito:20200323202427g:plain:w300
活発に活動する場合

灰色が健康な粒子、赤が感染した粒子、緑が治癒した粒子です。

以上の様に、初めの感染が起こった時から爆発的に感染が拡大します。

半分の粒子の活動が不活発な場合

f:id:kouhei_ito:20200323205713g:plain:w300
50%が不活発な場合

立ち上がりが遅くなり、ピークの粒子数も少なくなる、完全に収束するまでには少し時間がかかりますね。

90%粒子の活動が不活発な場合

f:id:kouhei_ito:20200323211422g:plain:w300
90%が不活発な場合
ほとんどの粒子が外出制限している状態です。この場合は封じ込められているような気がします。

全ての場合の比較

最後に一覧にして示します。

f:id:kouhei_ito:20200327124806g:plain
全ての場合の比較

プログラムの中身

沢山の粒子を生成しないといけないのでオブジェクト指向的にコーディングしてみました。

プログラムの中身はピープル(粒子)クラスの中でそれぞれ、座標と速度ベクトルを管理しています。

f:id:kouhei_ito:20200324082638p:plain:w400
ピープルクラスの概要

WPの計算と違うのは、WPは衝突すると完全弾性衝突みたいな動きをしていましたが 僕の計算は近づいたら、速度ベクトルをランダムに変えるアルゴリズムにしました。

各粒子との濃厚接触の確認が総当たりなので遅いです。それでも、最初は一度既に確認したペアも確認していたので、 それを改善したらだいぶ速くなりました。

ここんところは本業の人は空気を吸うように速いアルゴリズムを採用されるのだと思いますが、僕はまだ修行がたりず、 力技のコーディングしかできず、恥ずかしい限りです。

本当は実行しながら、アニメーションがみられるプログラムにしたかったんですが、遅すぎて無理だったので 画像をフォルダ1枚づつに吐き出して、最後にGIFアニメにまとめてます。

一応、Jupyter notebook用の美しくないコードをここに晒しておきます。

github.com

おわりに

まあまあよくできた

WPに刺激されて自分で書いてみました。もっと、本物に似せられるかなと思たんですけどねえ、なかなか難しかったです。

コロナウイルス対策としては、外出の自粛は効果あるんだなあと言う実感をもちました。

GIFアニメもいいね

プログラミングですが、これまではリアルタイムでぐりぐり動くのが良いかなと思っていたのですが、 シミュレーションが好きでやってみたい人にとっては、今回のように一枚づつ画像を生成して GIFアニメにして、後から動画として楽しむのも良いなと感じました。自分でつくったGIFアニメ 何回も見て楽しんでいます。(笑)

しばらくは自粛で

とりあえず今後はマスクは忘れずに

  • ある程度離れて
  • 換気をして
  • 面と向かって話し合わない

以上を心がけましょう。 おそらくまだ、落ち着いたわけではないと思います。

では、また!