■ No.14 (2002.02.06) … ランダムさ III

今回は,ランダムさがもつ性質についてまたまた違う角度から調べてみよう. で,今回は乱数で現実世界をシミュレートしてみる試みを行ってみる. こうした試みをより複雑に精密に行えば,それは実用レベルにも達するだろうし,その過程で数学や現実世界への新しい知見も得られるだろう.

酔っ払い親父の足どり(ランダムウォーク)

ここでは酔っ払いの千鳥足の挙動を乱数を用いてシミュレートしてみよう. まず,この酔っ払いはあまりに酔ってしまったため,一分に一歩しか進めない. しかも,前か後ろにしか進めない状態だ, という最もシンプルな場合を考えよう.
# つまり,「次」の可能性が二通りしかない.

そして,さらにシンプルに,前に行く確率が 1/2, 後ろに行く確率が 1/2 だ,としよう. すると,n 分後にはこの酔っ払いはスタート地点からどれくらい離れた場所にいるだろうか. まずは Mathematica で試してみよう.

    In[1]:= Needs["Graphics`"];    ← 必要になるので,一番最初に忘れないようにやっておく.
    In[2]:= Needs["Statistics`"];  ← これも必要になる. 

    In[3]:= Random[Integer]        ← 確かこれで 0 か 1 が確率 1/2 で出てくる.
    Out[3]= 1    

    In[4]:= Table[Random[Integer], {100}]  ← 試しに 100 回やってみる.
    Out[4]= {1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 
             1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 
             1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 
             0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1}

    In[5]:= % /. 0 -> -1   ← 「前へ行く = +1」「後ろへ行く = -1」としておくといろいろ都合が良さそうなので,
                               0 を -1 に置換しておく.
    Out[5]= {1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 
            -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 
            -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 
             1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 
            -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1}
            ← これが「酔っ払いが100分の間に前へ行ったか,後ろへ行ったかのリスト(^-^)」

     In[6]:= FoldList[Plus, 0, %]    ← 左から順に 0 に足していくと…
     Out[6]= {0, 1, 0, -1, -2, -1, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 10, 11, 10, 11, 12, 
             13, 12, 11, 12, 11, 12, 13, 14, 13, 14, 13, 12, 11, 12, 11, 12, 13, 14, 15, 
             14, 15, 14, 15, 14, 15, 14, 13, 14, 13, 14, 13, 12, 11, 10, 9, 10, 9, 10, 11, 
             12, 11, 10, 9, 8, 9, 8, 7, 6, 5, 6, 5, 4, 3, 4, 5, 4, 5, 4, 3, 4, 5, 4, 3, 4, 
              3, 2, 1, 0, 1, 0, -1, -2, -1, -2, -3, -4, -3, -2}

     In[7]:= Delete[ %, 1]  ← 上の結果の最初の 0 は意味ないので削る.
     Out[7]= {1, 0, -1, -2, -1, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 10, 11, 10, 11, 12, 
             13, 12, 11, 12, 11, 12, 13, 14, 13, 14, 13, 12, 11, 12, 11, 12, 13, 14, 15, 
             14, 15, 14, 15, 14, 15, 14, 13, 14, 13, 14, 13, 12, 11, 10, 9, 10, 9, 10, 11, 
             12, 11, 10, 9, 8, 9, 8, 7, 6, 5, 6, 5, 4, 3, 4, 5, 4, 5, 4, 3, 4, 5, 4, 3, 4, 
              3, 2, 1, 0, 1, 0, -1, -2, -1, -2, -3, -4, -3, -2}

     In[8]:= ListPlot[%, PlotJoined -> True]
                 ← 横軸=時間,縦軸=スタート地点からの前進距離(^-^)
    

ただし,途中で使った Mathematica の新しい関数は,以下の通りである.

● 変換規則の適用 … 式 /. 変換ルール
→ 変換ルールは,a を b に変換したいとき,a -> b と書く.
→ 例えば,x + y /. x -> 3 とすると,答えは 3 + y になる.


● 関数を引数に繰り返して適用した結果を並べる … FoldList[関数, 引数, リスト]
→ Nest に似ているが,関数の第二引数がリストの要素になる.
→ 動作自体は Fold と同じだが,計算履歴が全部リストとして出力される点が異なる. Nest と NestList との関係と同じ.
→ 例えば,FoldList[f, x, {a, b, c}] は {x, f[x,a], f[f[x,a],b], f[f[f[x,a],b],c]} になる.

例えば,((1.32)0.7)1.2 を計算するには以下のようにする.

    In[1]:= FoldList[Power, 1.3, {2, 0.7, 1.2}]
    Out[1]= {1.3, 1.69, 1.44385, 1.55391}
    

● リスト の要素を削る … Delete[リスト,要素番号]
→ Delete[{a, b, c, d}, 3] とすると答えは {a, b, d} となる.

さて,これの繰り返しを毎回入力するのは面倒なので,縮めて関数にしてしまおう. 酔っ払いの前後歩きそのもののリストを出力する関数を RW[全歩数], その結果によって,n 歩目でスタート地点からどれくらい前進しているかのリストを出力する関数を RWpath[全歩数], ついでにその結果をプロットする関数を RWplot[全歩数] として作ってみる.

    In[9]:= RW[num_] := Table[Random[Integer], {num}] /. 0 -> -1

    In[10]:= RW[100]   ← 試しに酔っ払い親父に 100歩歩かせてみる.
    Out[10]= {-1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 
              1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 
             -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 
              1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 
             -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1}

    In[11]:= RWpath[num_] := Delete[FoldList[Plus, 0, RW[num]] , 1]

    In[12]:= RWpath[100]   ← やはり同様に試してみる.
    Out[11]= …略…

    In[13]:= RWplot[num_] := ListPlot[RWpath[num], PlotJoined -> True]

    In[14]:= RWplot[100]   ← やはり同様に試してみる.
    Out[14]= …略…
    

さて,これで酔っ払い親父にいくらでも歩かせて,その過程をグラフで見る ことが簡単にできるようになった. では,その結果についてなにかこの時点で予想できるか? 何度もやったり,全歩数を変えたりして,何か知見が得られないか試してみよ.
例えば,同時に多くの親父に歩かせて,その経路を重ねて表示するという, 次のようなグラフを得るにはどうやってみたらよいか. → (授業中の課題)

    
          ← 横軸=時間, 縦軸= 各々違う親父の位置(^-^)
      
    



平均

さて,まずは誰でもわかる簡単な予想を形にしてみよう.

■ 仮説 1 n 歩後の酔っ払い親父の前進位置の「平均値」はゼロである.

これは,「前進」と「後退」の確率が全く等しいのだから,どちらへ進んでいると考えるのも不合理だ,という直感的な考え方で理解できる.
さて,これを Mathematica で確認してみよう.

RWpath[n][[-1]] (Last[ RWpath[n] ] と書いても同じ) で酔っ払いに「一回」 n 歩歩かせた時の位置が求まるので, それを m 回やらせてみよう.

    In[15]:= RWmulti[num_, m_] := Table[ RWpath[num][[-1]], {m} ]   ← 親父を num 歩歩かせる,というのを m 回行う.
                                                                       その時の最後の位置を各々出力する.

    In[16]:= RWmulti[100, 5]          ← 100歩歩かせる,のを 5回 ためしにやってみた.
    Out[16]= {-2, -14, -16, -4, 10}   ← こんな感じだ.
    

さて,平均値は Mathematica で

● 平均値 … Mean[数値のリスト]
→ 全部足して個数で割るだけ.
→ 事前に Needs["Statistics`"]; が必要… ないかもしれない. (マニュアルに「かもしれない」と書いてある(^-^)) ま,一応やっておけ.


で簡単に計算できるのでそれを使ってみよう.

    In[17]:= RWmulti[100, 500];            ← 100歩歩かせる,のを 500 回. 本当にやらせたら,完了する前に寝てしまいそうだ.

    In[18]:= Mean[ %17 ] // N
    Out[18]= -0.176            ← ふ〜む,まあ 0 に近い,といえなくもないな.

    In[19]:= Mean[ RWmulti[100, 1000] ] // N    ← 100歩歩かせる,のを 1000 回の場合の平均は…
    Out[19]= 0.04      ← ふ〜む,0 に近くなったような気がするな.
    

さて,本当に仮説 1 は正しいかどうか,歩数や歩かせる回数 (ランダムな実験を試す回数を試行回数という. 上の例だと,500 とか 1000,という部分が相当する) を変えて,調べてみよ. → (授業中の課題)

□ レポート課題 1
仮説 1 を証明せよ. (n 歩後の位置の平均値を loc(n) と書き,loc(n) が分かっていると仮定するとloc(n+1) はどう計算されるか,を考えれば簡単 )

標準偏差

さて,平均値については仮説 1 でチェックするものとして,他のことを考えよう.
親父の足取りグラフを見ていると,けして位置 0 近くにだけずっといるのではなく, 結構遠くまでさまよい歩いていくことが見て分かる.

このさまよい歩きの「程度」を知るにはどうしたらよいだろうか? 平均では,歩いていった効果がプラスマイナスで打ち消されてこうした程度が見えなくなってしまう.
そこで,n 歩後の位置の「絶対値」に相当する量を使ってみよう. これならプラスマイナスで打ち消されることはない. 数学にはこうした時に便利な量がある.

■ 分散
確率的な値(例えば,親父の n 歩後の位置)の分散とは, (値 - 平均値)2 の平均値のことである.
→ 要するに,平均からのズレの二乗がだいたいわかるということだ.

■ 標準偏差
確率的な値の標準偏差とは, ��(分散) のことである.
→ 要するに,平均からのズレが(絶対値で)だいたいわかるということだ.

(注意!!) 実は,上の分散,標準偏差の定義は確率的な値をとる量そのもの,に対する定義であり, その量が実際に示したサンプル値の集合,つまり,今回の数字の列など, に対しては異なる定義の分散, 標準偏差を用いた方が何かと好都合であることが知られている.
そのためか,Mathematica に組込まれている分散,標準偏差の関数は 「サンプル値集合用」になっており,上の定義とは異なる.
しかし,その定義や理由を示し,理解するにはだいぶ準備が必要なので, 今回はこの単純な定義のものだけを示すにとどめる.
ちなみに,その違いは非常に小さく,n → ∞ でゼロになるので,実際, 今回は気にするほどでもない.


この標準偏差を使えば,親父がだいたいどこまでさまよい歩いていっているのか, その程度が計算できる. そこで,標準偏差を計算する関数を作って使ってみよう.

    In[20]:= SD[a_] := (
               Apply[Plus,
                 Map[(# - Mean[a])^2 &, a]
                 ] /Length[a]
               )^0.5     
              ← 真面目に標準偏差を計算する. 計算量は無駄がある.

    In[21]:= SD[ RWmulti[100, 500] ]     ← 100歩歩くのを 500回やらせてみて,どれくらい平均値(=0)からズレるのかというと…
    Out[21]= 10.4486        ← だいたい 10歩分ぐらい遠くに行っていることが多い,ということだな.

    In[22]:= RWsd[num_] := SD[ RWmulti[num, 500] ]   ← num 歩後の位置の平均からの大体のズレ,を示す関数.

    In[23]:= RWsd[100]       ← ためしに In[21] と同じ計算をしてみると,
    Out[23]= 9.27146        ← だいたい同じ値になった.
    

さて,この関数 RWsd[歩数] を使って,親父がどれくらいふらふら歩いていったか,をグラフにしてみよう.

    In[24]:= Table[RWsd[n], {n, 1, 200}];  ← 1 〜 200歩の場合について,各々どれくらい平均から離れているか,をリストアップ.
                                              結構計算時間がかかるので,{n, 1, 200} の部分を {n, 1, 100, 10} 等に直してやった方がよいかも.

    In[25]:= ListPlot[%24, PlotJoined -> True]
                 ← 横軸=時間, 縦軸=位置の標準偏差=平均からのズレ
    

ほう. こうしてみると,平均(今回はゼロ)からの「ズレ」,すなわち標準偏差は歩数 n ときちんとした関係がありそうだ.
では,その関係を調べてみよう. こうした,グラフにきれいな関係があるときは「対数グラフ」に直してみろ, というのがいつもの鉄則なので,そうしてみよう.

    In[26]:= LogListPlot[%24, PlotJoined -> True]        In[27]:= LogLinearListPlot[%24, PlotJoined -> True]
                               

                      ↑ y 軸を対数に. あんま嬉しくない結果.                    ↑ x 軸を対数に. あんま嬉しくない結果.

    In[28]:= LogLogListPlot[%24, PlotJoined -> True]
                 ← x, y 軸の両方を対数に.  おお,きれいな直線に!!
    

ただし,途中で

● データのグラフを片対数(対数軸 = x軸)で描く … LogLinearListPlot[リスト]
→ x 軸だけを対数にしたグラフを描く.
→ Needs["Graphics`"]; を事前に行う必要あり.


を用いている.

さて,両対数グラフを見ると,きれいな直線の関係が見て取れる. つまり,比例関係,ということである.
比例関係ということは,数式で表わせば,

    log(y) �� a * log(x) + b       ⇔       y �� eb * xa
    

ということだから,なんとかしてこの a,b を求めればかなり細かいことが仮説として言えることになる. そこで,以前習った「グラフ上のカーソルの場所の値を調べるテクニック」 を使って,この直線上の二点ほど座標を拾ってみると,

    (log(x), log(y))  �� (1, 0.5),
    (log(x), log(y))  �� (2, 1)
    

の二点が得られる(もちろん他の座標を拾ってもよい). これを上の式に代入してみると,

    0.5 �� a * 1 + b
    1   �� a * 2 + b
    

ということであるから,これは a �� 1/2, b �� 0 ということであり,つまり, y �� x1/2 ということになる. 確認のため,その理論グラフと実験グラフを比べてみよう.

    In[29]:=  DisplayTogether[
                LogLogListPlot[%24, PlotJoined -> True],
                LogLogPlot[x^0.5, {x, 1, 200}, PlotStyle -> Hue[0]]
                ]

                 ← y =  x1/2 も赤で一緒にグラフ化. ほぼ一致することが良く分かる.

    In[30]:=  DisplayTogether[
                ListPlot[%24, PlotJoined -> True],
                Plot[x^0.5, {x, 1, 200}, PlotStyle -> Hue[0]]
                ]

                 ← 対数でないグラフ. やはりほぼ一致することが良く分かる.


    

ただし途中で

● 関数の両対数グラフを描く … LogLogPlot[関数,範囲]
→ x, y 軸両方を対数にしたグラフを描く.
→ Needs["Graphics`"]; を事前に行う必要あり.


を用いている.

さて,これで酔っ払い親父が n 歩後に平均値(= 0)からどれくらい離れているか, についてかなり精確な仮説がたてられる.

■ 仮説 2 n 歩後の酔っ払い親父の位置の標準偏差は,ほぼ n1/2 である.
(つまり,前後にズレているとして,そのズレの程度は n1/2 である.)

□ レポート課題 2
仮説 2 が成り立つわけを説明せよ. (証明,とまではいかなくても説明は,というレベル)
後で示す漸化式による確率分布計算を用いるのが良い. ただし,Taylor 展開等の数学的道具が必要になる… かも.

上の授業中の課題として与えられているような 「多くの親父が歩いた経路を同時表示するグラフ」 と,この仮説の結果をグラフで重ね合わせて,どうなるか見てみよ. → (授業中の課題)

漸化式による親父位置の計算

さて,この問題の親父の位置の確率分布( n 歩後に,位置 x にいる確率)は計算はできないのだろうか? 実は,簡単な計算を繰り返すことで求めることができるのである. これには,10000 人の親父が例えば同時に歩き出す,と考えて次のような図を考えると分かりやすい.


                 時間= n 分            n+1 分             n+2 分            n+3 分

                     (前)                                                          ワーイ   
                      |                  |                  |                  |  Q/
                    0 +                0 +                0 +        -→  1250 + /|
                      |                  |                  |     /           | < >
                      |                  |                  |   /* 0.5        |
                      |                  |                  | /               |  Q/
                    0 +                0 +        -→  2500 +                0 + /|
                      |                  |     /           | \               | < >
                      |                  |   /* 0.5        |   \* 0.5        |
                      |                  | /               |     \           |  Q/
                    0 +        -→  5000 +                0 +        -→  3750 + /|
                      |     /           | \               |     /           | < >
                      |   /* 0.5        |   \* 0.5        |   /* 0.5        |
          Q/          | /               |     \           | /               |  Q/
   Oyaji /|  … 10000 +                0 +        -→  5000 +                0 + /|
         < >          | \               |     /           | \               | < >
                      |   \* 0.5        |   /* 0.5        |   \* 0.5        |   ウィ〜
                      |     \           | /               |     \           |  Q/
                    0 +        -→  5000 +                0 +        -→  3750 + /|
                      |                  | \               |     /           | < >
                      |                  |   \* 0.5        |   /* 0.5        |
                      |                  |     \           | /               |  Q/
                    0 +                0 +        -→  2500 +                0 + /|
                      |                  |                  | \               | < >
                      |                  |                  |   \* 0.5        |
                      |                  |                  |     \           |  Q/
                    0 +                0 +                0 +        -→  1250 + /|
                      |                  |                  |                  | < >
                     (後)
                  ↑                                                        ↑
                 人数                                             人数的にだいぶばらけた


                            たくさんの親父酔っぱらって歩きまわるの図 

    

この図に即して考えれば,n 歩後(n 分後) に位置 x にいる人数を f(x,n) とすると,
0.5 * f(x-1,n) + 0.5 * f(x+1, n) = f(x, n+1)
という漸化式が成り立つことが分かる.
f は全人数で割れば確率と見なして良さそうだから,結局, n 歩後(n 分後) に位置 x に親父がいる確率 P(x, n) は
P(x, n+1) = 0.5 * P(x-1,n) + 0.5 * P(x+1, n)
で n = 0 から順に計算していけばよい,ということになる.
(注) 時間 = 0 では,親父は原点 x = 0 に確率 1 で存在する.

そこで,この漸化式に従って計算を進める関数を作ろう. n 歩後(n 分後)の親父の存在確率をリストにした リスト a(n) = {P(-m, n), P(-m+1, n),…, P(-1, n), P(0, n), P(1, n),…, P(m, n) } に対して, RWonedist[ a(n) ] とすると a(n+1) が出力されるようにしよう.

    In[31]:= RWonedist[a_] := Module[{num, b, result},
               num = Length[a];
               b = Append[Prepend[a, 0], 0];         ←  a(n) の前後にゼロをつけて,参照範囲に矛盾がないようにしている.
               result = Table[0.5 * b[[n - 1]] + 0.5 * b[[n + 1]], {n, 2, num + 1}];
                                                     ← これが上の漸化式による計算.
               Return[result]
               ]

    In[32]:= RWonedist[{0, 0, 0, 1, 0, 0, 0}]      ← ためしに上の図の一番左側相当をやってみると…
    Out[32]= {0, 0, 0.5, 0, 0.5, 0, 0}             ← 確かに!

    In[33]:= RWonedist[%]                          ← 続けると…
    Out[33]= {0, 0.25, 0, 0.5, 0, 0.25, 0}         ← これも上の図の通り.

    In[34]:= RWonedist[%]                          ← さらに続けると…
    Out[34]= {0.125, 0, 0.375, 0, 0.375, 0, 0.125} ← これもあっている.
    

ただし途中で

● リスト の先頭に要素を加える … Prepend[リスト, 要素]
→ Prepend[{a,b}, x] は {x, a, b} を出力する.

を用いている.

これで,初期値として 存在確率のリスト を用意して,RWonedist を n 回適用させれば n 分後の存在確率のリストが得られることになる. よって,そういう関数を(0 〜 n 分後までの結果を全部出すように作って) RWdist[初期値リスト, 歩数] として用意しよう.

    In[35]:= RWdist[a_, num_] := NestList[ RWonedist[#]&, a, num ]

    In[36]:= RWdist[{0, 0, 0, 1, 0, 0, 0}, 3]        ← ためしに上と同じことをやってみて確認.
    Out[36]= {{0, 0, 0, 1, 0, 0, 0}, {0, 0, 0.5, 0, 0.5, 0, 0}, 
              {0, 0.25, 0, 0.5, 0, 0.25, 0}, {0.125, 0, 0.375, 0, 0.375, 0, 0.125}}
    

これで,親父のいる場所の確率分布が直接計算できる,ということになった.
さて,上の例では親父のいる位置を 7個所しか考えなかったが,それでは狭すぎるので, 100個所程度に広げて,少し計算してみよう.

    In[37]:= Table[0, {99}]              ← 99 個の 0 が並ぶリスト.
    Out[37]= …略…

    In[38]:= a = ReplacePart[%, 1, 50]   ← 真ん中だけ確率を 1 に直して,初期値リスト,とする.
    Out[38]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

    In[39]:= RWdist[a,  200]             ← 200 歩後(分後)までの存在確率分布を計算.
    Out[39]= {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             …略…
              0.00101877, 0, 0.000666154, 0, 0.00041809, 0, 0.000241867, 0, 0.000110277, 0}}

    In[40]:= ListPlot[%39[[-1]], PlotStyle -> PointSize[.01], PlotRange -> All]

                ← 200 分後の確率分布.きれいな分布だ.

    In[41]:= Table[ 
               ListPlot[
                 %39[[n]], 
                 PlotStyle -> PointSize[.02], 
                 PlotRange -> All 
                 ],
               {n, 50, 200, 50}
               ]

    
             ↑  50,100,150,200 分後の確率分布.形状は同じだが,だんだん幅が広がるのがよくわかる.
    

これで,確率分布が計算できるので,親父が n 分後に位置 x にいる確率が厳密に分かる,というものだ.
ここで大事なのは, 確率的な現象の挙動が,乱数を使わずに計算できた ということである.

厳密に言えば,漸化式によって求まるのは,「たくさんの親父の挙動の平均」 とでもいうべきもので,「ある特定の親父の挙動」そのものを追えるわけではない.
そういう意味で,確率分布のグラフ(= 漸化式で求めたもの)を得ることを 「弱い解を求める」といい, 各親父の歩く経路を各々求めることを 「強い解を求める」といって区別する.
例えば,「結局 親父が全部でどれくらい歩くのか」というような問題は, 「弱い解」では答えがでない.


せっかく確率分布の理論値が計算できたので,それと実験値を比較せよ. → (授業中の課題)
# n 分後の 位置 x に親父がいる確率の理論値,と実験での頻度を比べてみるなどすればよい.
# 度数分布を使って比較すればもっとよかろう.

さて,せっかく沢山計算してあるので,それらの結果を一度に表示しておこう. これからも何か知見が得られるだろう…

    In[42]:= ListPlot3D[%39, PlotRange -> All]

       ← 確率分布が時間でどう変化していくかが一目で見える.

    

ただし,次の関数を用いている.

● 3 次元データのグラフを描く … ListPlot3D[3次元データリスト]
→ データリストは,高さを表わす実数の長方配列でないといけない.

おまけ… 中心極限定理との絡み

さて,上の In[41] でのグラフは皆似た形をしている. 幅の単位を変えればそっくりではなかろうか. これは本当か? そして,なぜだろう?

まず,前回も用いたヒストグラムを使って,この理論値がどれくらい実験値とあうものか,目で直接見て検証しよう. それには,前回の

    FreqRate[a_] := Map[
                      { N[ #[[1]]/Length[a] ], #[[2]] }&,
                      Frequencies[a]
                      ]  

    IRHistogram[a_] := BarChart[ FreqRate[a] ]  
    

を再び導入して,使ってみる.

    In[43]:= RWmulti[200, 500];            ← 200歩歩かせる,のを 500 回.

    In[44]:= IRHistogram[ % ]
                 ← 親父が 200歩後にどこにいるのか.  その確率分布(実験値).
    

In[44] の結果を In[40] の結果と比較すれば,理論値と実験値の比較ができる. やってみよ. → (授業中の課題)
さて,さらに多くの実験結果の分布をみてみると…

    In[45]:= Table[
               IRHistogram[ RWmulti[n, 500]],
               {n, 50, 200, 50}
               ]

    
             ↑  50,100,150,200 分後の確率分布実験値.形状がほぼ同じだ.
    

まず,上の結果を In[41] の結果と比較せよ. 理論と実験はそれなりに合うだろうか.→ (授業中の課題)

□ レポート課題 3
さらに In[42] に相当する実験結果のグラフを作成し,In[42] のグラフと比較せよ.

さて,上の結果を見ると,親父のいる位置の確率分布の実験値は形状的には同じ形状に散らばるようだ. しかも,その形状はどこかで見たような形をしている.
よく思い出すと,前回示した仮説 4,もしくは「中心極限定理」の個所ででてきたグラフにこのグラフはそっくりである. これは偶然だろうか? 考えてみよう.
歩数をさらに増やすなどして,同様に調べてみよう. → (授業中の課題)

□ レポート課題 4
上で得られたグラフは前回示した仮説 4,もしくは「中心極限定理」の個所ででてきたグラフによく似ている. その理由を述べよ.
(親父が n 歩後にいる位置とは, +1 か -1 になる乱数を n 回足したものである,と考えると…)

さて,このグラフと中心極限定理との関係の理由はレポートで考察するとして, これを(理由抜きで)事実部分を記述して仮説にしておこう.

■ 仮説 3 n 歩後の酔っ払い親父の位置は,中心極限定理になんらかの形で従う. つまり,その位置分布の形状は n → ∞ で中心極限定理の示す形になる. しかも,その時の平均は ゼロ,標準偏差は n1/2 になる.

さらなる考察 … ややこしい親父だったら?

さて,今回の酔っ払い親父は,前後にしか移動せず, しかもどちらへ行く確率も 1/2 と同値という簡単な親父だった(^-^).
では,も少しややこしい設定の場合は,上の全ての解析はどうなるだろうか? 例えば,
前へ行く確率 = 1/3, とどまっている確率 = 1/3, 後ろへ行く確率 = 1/3
だったらどうなるだろう? 他の場合は?

□ レポート課題 5
適当に親父の挙動を設定して,自分でこの章と同様の解析を行ってみよ. 異なった結果,同じだった結果,各々について,なぜ異なったのか,同じだったのか,を考察せよ.

>> 目次