2019.04.25

群れっぽい動きをシミュレーションしてみた

Pocket

こんにちは。令和になるのが楽しみな次世代システム研究室のJK(男)です。元号が変わるというのは思ったより良いもんですね。失われた何年とか暗い話は置いていき、良い時代にしていきたいです。

そんなわけで(どんなわけだか、、)今回はこれまでと少し趣向を変えて、書籍「作って動かすALife」の第4章を参考に”群れ”について調査した結果について書いていこうと思います。これは以前のブログのマルチエージェント強化学習の話題と似ている部分もありまが、以前の話は各エージェントが賢く(= ニューラルネットを持っていて)学習をしていくという話でした。今回は”無脳”(≠無能)モデルなので学習はしません。

社会への応用があるのかは不透明ですが、単純なアルゴリズムで生命っぽい動きをするところがエモかったので紹介します。完全なる趣味ですね。。ブログは以下の構成になっています。
1. ボイドモデル (再現実験1)
2. 餌あり・ボイドモデル (再現実験2)
3. 外敵あり・ボイドモデル (オリジナル実験1)
4. ランダム・ボイドモデル (オリジナル実験2)

今回の実験ノートとコードはGitHubにあげていますので、興味のある方は参考にしてください。

1. ボイドモデル(再現実験1)

まず最も単純なボイドモデルについて簡単に説明します。詳細は書籍”作って動かすALife”(以下、テキスト)4章を参照してください。ボイドモデル (Boid model) とは、bird-oid (鳥っぽい) から作られた造語だそうです。要は鳥の群れっぽい動きを再現するモデルってことですね。こんな感じです。


V1-1. ボイドモデル(default)

このモデルは学習せず、最初に設定された少ないパラメータに従い、単純なアルゴリズムに従って個体は動きます。そのため1 stepあたりの(各個体がどう動くかの)計算量が少なくすみ、多くの個体(この実験では256個体)〜「群れ」のシミュレーションができます。注意してほしいのは、動きは個体ごとに計算されており神の視点のようなものは無いということです(細かい事を言うと微妙ですが、だいたいこの解釈で合ってるはず)。神様が鳥瞰的に”群れ”という集団を操作しているわけではなく、各個体が(アルゴリズム〜自己判断)することで、まるで1つの意思を持ったかのような”群れ”の動きになるのです。また個体は学習しないので、アルゴリズム(〜判断能力)は常に完全に均質です。初期条件が異なることで、このような面白い動きが生まれるのですね。

今回のモデルでは3つの力(結合、分離、整列)が考えられています。「結合」は個体同士が近付こうとする力、「分離」は離れようとする力、「整列」は動く方向を揃えようとする力です。それぞれ、力の大きさ、力が及ぶ範囲と角度がパラメータとして設定できます。これら3つの力の合計で個体の動きが決まります。詳しいパラメータについてはテキストやGitHubのconfig fileをみてください。当然、力のパラメータを変更すると個体の動きが変わり、群れの動きも変わります。ここでは、テキストで紹介されているパラメータで設定された群れを2つ紹介します。他のケースについてはGitHubをみてください。


V1-2. ボイドモデル(torus)

上記はTorusと呼ばれるタイプの群れだそうです。開始早々、群れが円弧を描くようになりますね。この群れのパラメータはV1-1と比べると、結合と整列の力の大きさは弱く、しかし力の及ぶ範囲は広く取っています。広く弱くつながり弱く整列することで、このような円弧の群れができます。面白いですね。


V1-3. ボイドモデル(dynamic parallel)

こちらはDynamic parallelと呼ばれるタイプのようです。動画の20秒あたりで、大きな群れの塊ができて、それらが高速で移動しているのがわかると思います。V1-1のパラメータと比べると、整列の力の及ぶ範囲が広いです。群れの塊ができるから、結合の力が強いのかと思いましたがそうではないようです。実は結合の力を強くしても群れの塊はできるのですが、塊の中心に動く力が強いため素早い移動にはなりません。整列の力をdominantにすることで、V1-3のようにdynamicに動く群れが作れるのですね。

2. 餌あり・ボイドモデル (再現実験2)

自然界の群れの創発は生存戦略の中で生まれてきたと考えられます。つまり群れができたのは、生き残る目的に適っていたからでしょう。ここでは餌を手に入れるという”目的”を導入してみます。この章もテキストの再実験です。まず動画を見てください。


V2-1. 餌あり・ボイドモデル(default)

上のように、個体は餌(=赤玉)に向かっていきます。餌は一定時間を過ぎると、ランダムな位置に移動します(で、また餌に向かって個体が群がる)。このモデルでは、個体の動きを計算する際に、1章で説明した力に「餌に向かって動く力」を加えています。単純ですね。いくつかのパラメータセットで実験してみましょう。


V2-2. 餌あり・ボイドモデル(torus)

V1-2と同じパラメータセットの群れに餌を与えています。餌に群がっているのはV2-1と同じですが、複数の個体が餌から離れて行動する場合がありますね。群れを作る力の方が餌への吸引力より強くなり「はぐれ群」を作ったようです。


V2-3. 餌あり・ボイドモデル(dynamic parallel)

V1-3と同じパラメータセットの群れに餌を与えています。餌に群がっているのはV2-1, V2-2と同じですが、やはりパラメータセットの特徴が見えますね。特に餌が移動した瞬間、個体が中心から放射状に離れていくのがわかります。整列する力が強いため(餌による吸引力がなくなった瞬間)、そのとき向いていた方向に進んでしまうようです。

3. 外敵あり・ボイドモデル (オリジナル実験1)

2の実験の「餌に向かっていく力」の大きさはパラメータで制御しています。ということは、力の符号を反転させると逆に赤玉から逃げるような動きになるはずです。実験してみましょう。


V3-1. 反転した餌あり・ボイドモデル(torus)

この場合、赤玉は餌ではなく「外敵」と解釈できそうです。上記の設定では、外敵がたまにしか動かないので、群れの動きがあまり面白くなりませんね。そこで外敵が群れを追いかけるように設定を変えて実験しました。以下のようになります。


V3-2. 外敵あり・ボイドモデル(default)

V1-1と同じdefaultのパラメータセットに「外敵から逃げる力」が加わっただけですが、それによって随分と群れの動きが変わりました。まるで意思を持った1つの個体のように群れが動いていますね。私はこれを見て小学校の教科書で見たスイミーを思い出しました(スイミーは外敵を追い払うので、動きが逆ですが笑)。面白いのは、(スイミーーの場合と異なり)各個体は「群れを作ろう」とは全く思ってないことです。ただ他の個体の動きと合わせたり外敵から逃げようと各個体がするだけで、このような群れが形成されます。


V3-3. 外敵あり・ボイドモデル(torus)

V1-2と同じtorusのパラメータセットに「外敵から逃げる力」が加わっています。面白いことに、V3-2に近い動きになっていますね(V3-2が魚ならこちらは龍とか蛇っぽい動き、という違いはありますが)。


V3-4. 外敵あり・ボイドモデル(dynamic parallel)

こちらはV1-3と同じdynamic parallelのパラメータセットに「外敵から逃げる力」が加わっています。やはり似たような群れの動きになっています。

面白いことにV3-2~V3-4は似たような群れの動きになりましたね。群れが(外敵から逃げる力以外は)1と同じ設定の場合比べてalignされているがわかります。「整列する力」がある程度ある個体群において、外力(外敵から逃げようとするetc)がかかると、似たような動きになるようです。このことから、外敵から逃げるという”共通の目的”が群れを作る上で重要そうだなぁという事が推測できます。

ただ少し機械的に動いているように見えます。まぁ実際、機械的に(アルゴリズムに従って)動かしているので当たり前なのですが。。

4. ランダム・ボイドモデル (オリジナル実験2)

3の実験の結果は面白かったのですが、少し機械的な動きになってしまうのが個人的に不満でした。より”生命っぽい”動きにするにはどうするか?1~3の実験ではstep毎に、256個体全てを(そのstepでかかる力を計算して、次に動く位置を)更新しています。しかし実際の生命において、全ての個体が同じタイミングで(=同期して)更新されることはないでしょう。そこで少し非同期性を入れるため、1 stepで更新される個体数の割合をパラメータとして導入しました(update_ratio) 。たとえばupdate_ratio=0.7なら、1 stepで更新される個体数は、256*0.7 = 179個体になります。選ばれる個体は毎stepランダムに決めます。たとえばV3-2と同じパラメータセットでupdate_ratio=0.7にした場合、以下のような動きになります。


V4-1. 外敵あり・ランダム・ボイドモデル(default)

V3-2とは随分異なる群れになりましたね。(更新されないため)周りの動きに同期しない個体が一定数いるため、メインの群れの動きとは別行動する個体が現れ、それに追随する個体もできるため、V3-2のときのようなスイミー的な群れは構成されなくなったようです。

同様にV3-3とV3-4のパラメータセット(で、update_ratio=0.7にした場合)でも試してみましょう。


V4-2. 外敵あり・ランダム・ボイドモデル(torus)

一見、V3-3の場合とあまり変わらないように見えますが、群れの動く方向が、メインの群れとは別の小群によって決まる場合もあります。V3-3の単調な動きと比べるとよりdynamicな動きになっていることがわかります。


V4-3. 外敵あり・ランダム・ボイドモデル(dynamic parallel)

V3-4と比べると群れがばらけていて、おおまかな群れの方向性はあるものの、それから外れる個体などもいますね。

V3のときとV4を全体的に比較してみると、群れが機械的な往復運動にならずdynamicな動きになる傾向になるのがわかります。個人的には、こちらの方がより生命っぽい感じがします。実際、あまりに統率が取れすぎた群れだと、(逃げた方向に別の外敵などいたら)一気に死ぬ可能性もありますね。ある程度、メインの動きから外れたような個体もいた方が(多様性がある方が)より生き残れる可能性は高くなるでしょう。そんなわけで生命っぽい感じの群れを作るには、非同期性(もしくは異質性)も重要な気がします。

まとめ

書籍「作って動かすALife」4章を参考にして、群れの動きについて実験をして考察しました。シンプルなアルゴリズムで群れの動きをある程度再現できるのは面白いです。実験から餌や外敵のような外力を導入することで、より群れの動きが洗練されることがわかり、このような外力が群れの創発に重要な意味を持っているだろうことが推察できました。また非同期的な更新をして群れに異質な動きを入れることで、より生命っぽい動き(柔軟な動き)を再現できたように見えました。このような簡単な実験で、自然界で起きている事を色々と考察できるのは楽しいですね。今回は個体は学習しませんでしたが、今後は群れを進化させるなどもやれたら面白いかなぁと思ったりしてます。

 

次世代システム研究室では、ビッグデータ解析プラットホームの設計・開発を行うアーキテクトとデータサイエンティストを募集しています。ご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。