mmm2

 第5回 DLAパターンとアリの採餌モデル(11月8日)



*出席確認

<出席確認メール> 添付ファイルなし 受付:本日14:30〜16:15

本日のキーワードは授業中に連絡します。


宛先:miwamoto[at]riko.shimane-u.ac.jp

件名:MMM2 20161108

本文: 学生番号 名前 「本日のキーワード」



*岩本研究室訪問(4月からゼミ配属予定で岩本研を希望する人)

12月7日(水)13:00〜14:30 

総合理工学部1号館8階解析系セミナー室にて4年生ゼミを公開をします。

岩本研を希望する人は見学に来てください。

途中退室可としますが、始まりの時間は必ず来てください。

見学に来た人は研究室訪問の名簿に名前を書いてください。

(この日程で都合が悪い人は、相談しにきてください。)





DLA パターン



このブラウザは埋め込まれたオーディオファイルを再生できません



DLAパターンの作り方 ヒントその1:整数の乱数の生成


乱数はrandom(10,20)などを使うと作ることができるが、標準では実数値である。つまり、random(10,20)とすると、10以上20未満の実数値が生成される。

しかし、整数値のみの乱数が使いたいことがある。その場合は、以下の方法のいずれかを使うと良い。

小数点以下を切り捨てる

floor(random(10,20))

例えば、ランダムウォークさせる部分は、次のように書くことができ、コードを短くすることができる。

小数点以下を四捨五入する

round(random(10,20))

 x[i] += round(random(-1,1));

 y[i] += round(random(-1,1));

小数点以下を切り捨てる

ceil(random(10,20))

注意:この場合は0も生成される。


*そのほかint(random(10,20))とintでキャスト(型を変更)する方法もある。


DLAパターンの作り方 ヒントその2:フラッグを立てる


DLAシミュレーションの粒子は、自由粒子と種粒子がいる。粒子がどちらの状態であるかを知る必要がある。そこで、状態を表す変数flag(整数型int)を用意する。

例えば、

・i番目の粒子が自由粒子ならflag[i] = 0とする。(旗をあげない)

・i番目の種粒子ならflag[i] = 1とする。(旗をあげる)

旗があがっていない粒子は動けるが、旗をあげた粒子は動けない。


DLAパターンの作り方 ヒントその3:アルゴリズム(基本のみ)


①変数の宣言

・粒子の数(数を代入しておく)particlenum

・自由粒子の位置(配列で用意)

・種粒子の位置(配列で用意)

・種粒子の数(宣言のみで数は入れない)seednum

flag旗の配列(自由粒子の数だけ必要)

・int count; (flagがあがった数を数える)


②setup関数に初期値を入れる

void setup()

{

 サイズなどの設定

   for(int i =0; i < particlenum; i++)

   {

    ・自由粒子の初期位置

   ・flagを全て0に

   }

   種粒子の位置と数の設定(はじめは1つ)

}


③draw関数に時間発展を入れる

void draw()

{

 背景塗りつぶし

  count = 0; //countを初期化

   for(int i = 0; i < particlenum; i++)

   {

     if(もしflagが0だったら)

     {

        ランダムウォークする

       for(int j = 0; j < seednum; j++)

       {

         if(もし種粒子が隣にいたらor距離が○○以下だったら)

         {

          旗をあげる

         その粒子を種粒子にする

          count++;

         }

       }

     }  

   }

   seednum += count;


自由粒子の描画

種粒子の描画

}


練習1(前回の課題) DLAパターンのシミュレーションを作り、「dla_学生番号」として保存せよ。

生物の模様と数理モデル.001


練習2 DLAに確率を入れよ。つまり、種粒子に隣接すると、pの確率で種粒子に取り込まれるとせよ。pを変えるとパターンがどのように変わるか確認せよ。


練習3 自由粒子が画面を出ていかないように工夫せよ。


練習4(発展) 自由粒子が重ならないように工夫せよ。




ランダムウォークを利用した蟻の行動

ランダムウォークを利用しての行動をシミュレーションしよう。

餌を探しに出た蟻はどのようにして巣に帰るのか?

次のような観察結果がある。

  • 蟻は巣から出て、餌を探す時にはランダムウォークする。
  • 巣に帰るときには何故か巣の方向に向かってほぼ一直線に戻る


さらに観察すると、次のような事実がわかる。

  • 蟻は餌を求めるためにランダムウォークで動き回るが、動いたところにある種の化学物質(フェロモン)をつけて、足跡を残す
  • (餌を見つけるか、あるいはあきらめて)巣に帰るときには、付けた化学物質(足跡)の多い方へ向かって進む。(このとき、餌を見つけた蟻はそのことを知らせるために、別の異なる化学物質を足跡としてつける。)


(注意)蟻と言えば蟻の行列を思い浮かべる。上記の話は、行列を作る前の話である。

蟻は餌を探す時には上記の様なランダムウォークを行う。そのとき足跡フェロモンを分泌する。餌を見つけると、上記のようなルールで巣に戻るのであるが、そのときには道しるべフェロモンという別の物質を分泌し、巣に帰った後にその道しるべフェロモンをたどることで餌の場所に行列をつくりつつ、さらに道しるべフェロモンを強化すると言われている。


練習5 2次元配列を使って、1匹のがランダムウォークした軌跡を描画するシミュレーションを作成せよ。

ヒント1) 2次元配列の宣言

int x[][] = new int[particlenum][step];

ヒント2) 時間ステップ数

frameCount

ヒント3) 用意した配列より大きい数が入るとエラーになってしまうので、例えば1000ステップで止めると決めて、繰り返しループを止める。

if(frameCount >= 1000) noLoop();


補足:2次元配列について

例えば、

int a[2][3];

と宣言すると、

a[0][0], a[1][0],

a[0][1], a[1][1],

a[0][2], a[1][2]

の計6つ(2×3) の整数型の変数が用意される。

6つの変数に2重for文で値を代入することができる。

    for(int i = 0; i < 2; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            a[i][j] = i*j*sqrt(2.0);
        }
    }

これによって、

a[0][0] = 0

a[1][0] = 0

a[0][1] = 0

a[1][1] =  

a[0][2] = 0

a[1][2] =  

が代入される。



足跡を数える


蟻は移動するたびに足跡フェロモンを残すということが観察結果からわかっているので、足跡を数える仕組みをランダムウォークシミュレーションのプログラムに組み込もう。

考えている格子点全てについて、足跡を保持している変数を用意してやればよい。この場合、2次元配列変数を使うと簡単である。具体的には、

int count[][] = new int[x方向の格子の数][y方向の格子の数];

として宣言した配列変数 count に足跡の個数を記録する。


練習6 の足跡フェロモンの量を表示するシミュレーションを作成せよ。

ヒント1) 初期値として、count[i][j]の全てに0を代入せよ。

ヒント2) がその場所に来たらcount[のx格子][のy格子] += 1;

ヒント3) 塗りつぶしにcount[i][j]を使って、フェロモンの量を色で表現せよ。

  for(int i = 0; i < 100; i++)

   {

     for(int j = 0; j < 100; j++)

     {

       fill(255-min(255,2*count[i][j]));

       rect(i*5, j*5, 5,5);

     }


最小値を求める

min(a,b)

最大値を求める

max(a,b)

最大値最小値を求めるときは、maxやminを使用することが可能である。a,bに入るのは、int型かfloat型(同じである必要がある)で、最大3つまでの数を比較できる。




練習7 M匹の蟻が一斉に巣から出てくる状況を考える。このとき、各格子の足跡の合計をカウントし、画面に表示するプログラムを作成せよ。蟻の衝突は考えない。



巣に帰る蟻


足跡の分布は巣から離れるにつれて減少しているように見え、この傾向は蟻の数Mが大きくなるにつれ強くなった。


蟻の帰巣行動について、蟻は次の様なルールに従い、巣に帰るとする。

  • 蟻はある回数動くと、餌を見つけられたか否かによらず、(疲れたので)巣に帰る。
  • 巣に帰るときには化学物質量(足跡数)の多い方に向かって移動する。


蟻の帰巣行動をシミュレーションするための手順を考えよう。

最終的に到達した地点から帰巣行動をはじめるため、M匹の蟻それぞれがランダムウォークの結果到達した最終到達点の座標を記録しておく必要がある。

ヒント1)最終到達点の座標を記録しておく配列変数を用意する。

ヒント2)delayで指定した時間計算を停めることができる。括弧の中には数字を入れる。単位はミリ秒なので、次のようにかくと100ステップ目で3秒間計算がとまり、その後また始まる。

if(frameCount == 100) delay(3000);



本日の課題1 巣からランダムウォークして出て行った蟻が5秒間止まったのち、巣に帰るシミュレーションを作成せよ。は4方向をみてフェロモンの量が多い格子へ進むとする。

以下の点を工夫せよ。

① 4方向のうち、2方向以上のフェロモンの量が同じであった場合どうするか。

② 4方向に比べて自分のいるところの方がフェロモンの量が多い場合は動かない方が良いか。


本日の課題2(発展) ランダムウォークしたM匹ののうち、ある時間内に何匹が帰巣に成功するか調べよ。蟻の数を増やしたら帰巣に成功する蟻の数はどうなるか調べよ。