Scratch(ウィルス抗体率と感染率)

corona_beer_beachプログラム

久々の投稿です。いやぁ新型コロナウィルスが梅雨になって湿度が上がったら感染数が減るかとおもったらなかなか収束しないですね。IT企業に勤める私もリモートワークで、自宅から仕事をする比率も増えてきました。こんな時はITに強いところは柔軟性がありますね。

さてコロナ問題。前回はScratchを使いVirus感染について自由に行動するのか、密を避けて自粛するのがどちらが感染スピードが速いのかをシミュレーションしてみましたが、今回はどのくらい抗体が持っている人がいれば感染率が下がるのかをシミュレーションしてみました。

ウィルス感染(抗体率と感染率)

中身の確認はこちら
https://scratch.mit.edu/projects/414080725

 

プログラムの説明

このプログラムはウィルス感染について、抗体を保持している割合が感染にどう影響がでるかのシミュレーションです。

プログラムを開始すると、最初に全体の中で抗体を持っている人の割合、初期抗体率が何パーセントあるかを0~100で入力するボックスが現れます。入力が終わると、その割合に応じて緑と青の点が現れ、最後に1つの赤の点が出現します。点の数は300+1となっています。

赤が感染源、緑が抗体を保持している人(保持者)、青が抗体を持っていない人(非保持者)となります。抗体をもっていない人は赤に触れた場合に感染する可能性があり、感染すると青から赤にかわり、他の抗体非保持者に再び感染させてしまいます。ただ、感染してから15日間経過すると、抗体ができ緑の抗体保持者に代わります。

ここから100日が経過するまで各色の点が画面上に自由に動き回り、感染と回復を繰り返し、最終的に何人が感染し、感染率や最終抗体率がどうなるのかを見て取れるようになっています。

プログラムの説明

基本的な考え

基本的な考えは処理が始まると押すとクローンを作成するという処理とある色(赤色)に触れたら感染するという条件が発動するという部分が考え方となります。これは前回のVirus感染モデルのところでも説明したとおり、迷路ゲーム(みつばち出現版)でロジックは説明しています。

今回、これに対して最初に入力した割合で違う緑の点を出現させる処理と、感染率や感染ピーク数などの各種の計算を行う処理をいれているところが違う点でしょうか。

 

変数・配列の説明

Scratch_antibody_variable

いやぁ、今回、変数を作りまくってしまいました。本当にこれだけ変数が必要だったか、もう少し検討をすれば2~3個は減ったかもしれませんが・・・それは、このプログラムをみて皆さんが改善してみてください。

さて、一応、1つずつ説明しましょう。り患と日数、感染数は前回と同じなので説明を省きます。

感染数(ピーク)

感染した人がピーク時に何人であったかを示す変数です。こちらは最大値を求めるアルゴリズムを使っています。最大値アルゴリズムについてはこちらの記事

累積感染者数

トータルで何人感染したのかを足し算した結果を格納する変数です。

感染率(%)

累積感染者数や感染数(ピーク)だけだと、抗体率が低い場合は必然的に感染者数が多くなってしまいます。現在の東京で1日366人感染とか言っているのとおんなじで、それって多いの少ないの?を判断するために、感染率という指標を用いています。その数値を入れる変数です。

感染率(%)=累積感染者数 ÷ 抗体非保持者数(初期)× 100 で定義しています。

つまり、抗体を持っていない人の何パーセントが感染したのかを示す数値になります。

感染日

今回は感染してから15日経過すると回復するという処理としていますので、感染した日を記憶しておく必要があります。これは、クローンしたスプライト1つ1つが感染した日を記憶する必要があるのでローカル変数としていることに注意です。

抗体数

抗体数は抗体を持っている人の数です、初期値は入力した抗体率に応じた人数、つまり全体数×抗体率となります。その後、感染して回復者が増えると少しずつ抗体数は増えていきます。

抗体非保持者(初期)

こちらは抗体を持っていない人の数で全体数×(1-抗体率)となっています。ここで抗体非保持者(初期)というのをわざわざ作ったのは感染率を計算するためです。300-抗体保持者で抗体非保持者が計算できるでしょと最初考えていましたが、抗体保持者は、緑の点を作るときに使ってしまい、緑の点を全部出現させる際に変数の中身が0となってしまうため別途、この変数を作りました。(まぁ今思えば、緑の点を出現しきった後に、また抗体保持者に初期値を代入してやれば、この変数はいらなかったのかもしれませんが)

抗体保持者

抗体を持っている人の数で全体数×抗体率で計算されます。この変数は抗体保持者である緑の点を生成するためにつかわれる変数です。緑の点を全て出現させたら、この変数の中身は0になります

抗体率

この抗体率は全体300に対する抗体を保持している人の割合です。初期値は最初に入力したパーセント数になり、その後、感染して回復して抗体保持者が増えてくると抗体率も上昇していきます。

全体数

プログラムで出現させる点の数です。300としています。なお、感染源は特別にしており300とは別にしているので、正確にはプログラムの中に現れる点は300+1となります。

 

はい、変数多いですね。先にも書きましたが、もっと変数は減らせるはずです。皆さんトライしてみてください。

スプライトの説明

さてスプライトの中身の説明です。今回も1つのスプライトのみで構成しています。

青い点・緑の点・赤い点

Scratch-Virus-antibody_point

このスプライトの処理についてはこちらですが、ちょっと長くなるのでブロックを作って、処理をサブルーチン化させています。

全体の処理

Scratch_antibody001

まず左側部分の処理ですが、スタートを押した時に初期化処理がおこなわれ、その後、抗体率は何パーセントかと聞く処理が走り、その答えを元に抗体率と抗体保持者(初期)の値を決めます。そこから300回クローンを繰り返し点を増やす処理が始まります。そして最後に感染源である赤い点を作る処理にうつります。初期化処理と感染源の処理についてはサブルーチンにしていますので、後ほど説明します。

次に右側部分の処理は、クローンされた後の処理です。クローンされた後、全体数の変数を+1ずつしてクローンが何回行われているのかをリアルタイムに見る事ができます。その後、抗体を保持している緑の点を作る処理にうつります。その後は、繰り返しの処理となり、作成された青と緑の点がどう動くかの処理と、感染した際の処理、回復した時の処理、終了処理を設けています。抗体保持者の生成、感染処理、回復処理についてはサブルーチン化していますので後ほど

 

初期化の処理部

Scratch_antibody002

初期化処理はたくさん作った変数を一旦リセットする処理です。なんでこんなものがいるのっていう理由ですが、入れているのと、入れていない時の違いとして、プログラムを2回目以降に回したときにわかります。変数を初期化していないと、前の処理の結果の値が入っていて想定どおりの動作にならないため、最初に0や必要な数字を入れる処理を入れています。また、スプライトが最初にいる場所も座標(0,0)にし、スプライトが初期値は青い点であることにしています。つまり、赤い点や緑の点は青い点からの変化するものとなっています。

 

感染源の処理部

Scratch_antibody003

感染源である赤い点を出現させ、動き回らせる処理です。今回、感染源は1つだけで回復して抗体も持たず常に感染源として存在するものとなっています。まず処理が始まると感染源を示す赤い点になるようにコスチュームを赤に変更します。そして感染数と感染数(ピーク)を1にして、赤い点が現れた時点で感染数に関する初期化を行います。そして、感染源が現れた時点で日数をスタートさせたいのでタイマーをリセット。すなわちタイマーの初期化です。その後は自由に動き回りながらタイマーをカウントさせてて日数表示させます。終了条件は日数が100日を経過したタイミング。ここで日数=100とするのが正しいのですが、処理を複数にわけているからか、ぴったり100とすると止まらないことがあったので100以上という形で指定しています。

抗体保持者生成の処理部

Scratch_antibody004

抗体保持者の処理部は、抗体を持っている人、つまり緑の点を出現させる処理です。しかし、全てを緑にするわけにはいかないので、抗体保持者が0以上の時に緑になるようにしています。抗体所持者の変数は最初の処理で全体数×抗体率で算出しています。条件に合致した場合は、コスチュームを緑に変えて、抗体数を+1にし、逆に抗体保持者を-1にします。抗体保持者を-1にしているのは、この変数は緑の点を出現させるために利用している変数だからです。ここを-1しないと、無限に緑の点が出現してしまいます。そして、”り患”変数は2にしています。これは感染していない状態を0、感染した状態を1、抗体を持っている状態を2と定義しているからです。

感染判定の処理部

Scratch_antibody005

感染判定の処理部は赤い点に触れた際に処理が発動します。ただし、一度、感染したり、元々あるいは回復して抗体をもっている人に再び感染処理を適用させてしまわないよう。一度も感染していないことを示す”り患”変数が0の時というアンド条件としています。

条件に合致した場合は感染と言い、コスチュームを感染したことを示す赤にかえます。ここで、1秒待たせているのは感染したことをわかりやすくするためです。そして、感染数を+1、累積感染者数も+1、再び感染しないように”り患”を+1にしています。

今回のプログラムでは15日後に回復して抗体保持者になるようにしているので、感染したタイミングの日数を感染日という変数に格納しています。

さて、その後は感染者数のピーク値を求める処理です。ここは前にも書いた通り最大値のアルゴリズムをつかっています。

回復判定の処理部

Scratch_antibody006

回復判定の処理部は感染してから15日経過していることかつ感染者であることをしめす”り患”が 1であるときに発動します。15日経過はタイマー(プログラムがスタートしてからの経過時間)から感染した時の時間(感染した時のプログラムがスタートしてからの経過時間)を引き算して15以上であることで判断しています。

この条件が発動すると、回復と言った後、抗体保持者を示すようにコスチュームを緑にかえて、再び感染しないよう”り患”を 2 に変更、抗体数を+1、感染数を-1にします。

 

以上がプログラムの説明となります。

プログラムを動かした結果

では、このプログラムを動かして何がわかるのでしょう。正直なところ、前にも書いたとおり研究者がつくるような完全に正確なシミュレーションプログラムではないので結果が実世界を表すものではありません。そして、各点は自由に動き回っているので、感染源と触れる触れないには毎回バラバラで、同じ抗体率のパーセンテージを入力しても異なる結果がでます。ただし、そこは確率の世界なので一定の傾向はあります。

ここは、理系の基本、5回プログラムを流してみて、明らかな異常値ははずし、残った値の平均値をグラフ化していました。それがこちらです。

 

virus_holder_graph

この結果をみると最初の抗体保持者が多いほど、抗体非保持者が感染する数は少なくなり、感染率が低くなっていきます。一般的に抗体率が70%程度あると感染爆発を防ぐことができるといわれていますが、このグラフもだいたい60%あたりで、ぐんと減っています。(すいません、ほんとは10%刻みでグラフを作ればよかったのですが面倒くさくて区切りを適当にしちゃいました。グラフの傾きが数値を操作してるってみられちゃいますよね)

まとめ

さて、今回は新型コロナウィルス問題において、抗体率と感染率をScratchを使って疑似的にシミュレーションしてみました。

この結果や前回のVirus感染モデルからもわかるように、コロナ問題の解決は、ブラジルやスウェーデンのように行動自粛はせず、早期に抗体保持者を7割に達成させるか、ワクチンができるまで自粛して、ワクチン接種によって抗体保持者を7割に達成させるかになりそうです。

今回の新型コロナによって亡くなられた方にはお悔やみ申し上げます。ただ、感染症は新型コロナウィルスだけではありません。今回の件で感染症がいかに怖いものかわかった、強く自粛すべきと言われている方々には、ぜひ、今後は毎年のインフルエンザワクチンはもちろん、風疹や麻疹など感染すると一部の人に多大な被害をもたらすものについてワクチンをうっていただきたいと考えますね。

 

 

コメント

タイトルとURLをコピーしました