ジレスピ確率シミュレーションアルゴリズム
アルゴリズム 1
について、 連続マルコフ連鎖 の実現をシミュレーションする方法は ジレスピー確率シミュレーションアルゴリズムgillespie Stochastic Simulation Algorithm、短く SSAstochastic Simulation Algorithmと呼ばれている。
入力
初期値とを受け取る。
ステップ1.
を計算する。
ステップ2.
指数分布からをサンプリングする。が大きいほど、の期待値は小さくなり、事象は頻繁に発生する。
ステップ3.
の確率でを選ぶ。が大きいほど、事象が発生する確率が高くなる。
ステップ4.
を記録し、 のように更新する。は連続時間マルコフ連鎖なので、ステップ1に戻って繰り返し実行することができる。十分なデータを得たら、アルゴリズムを停止する。
出力
与えられたの実現を得る。
説明
例
アルゴリズムは式が一般的に書かれていて少し難しそうに見えるけど、実際はとても簡単だ。
簡単な誕生-死滅プロセスbirth-Death processを考えてみよう。このプロセスは人の人口から始まり、繁殖係数と死亡係数に従って人口の増減が表される。がより大きいか小さいかで異なる様相が現れるけれども、まず事象が発生する頻度そのものはこれらの絶対値に依存する。生存であれ死であれ、その時点での個体数に比例して頻繁に発生するのが妥当だし、人口数の時の事象が発生する間隔は に従う。一度事象が発生する時点を定めたら、次に発生する事象が誕生か死かを選ぶ。時点の人口数がの時、時点で繁殖するということは、死ぬということはを意味する。これらはそれぞれ係数と時点の人口数に比例するので、 ステップ3でこれらを正規化normalizeして得られる確率でどの事象が発生するかを決定すればいい。
コード
以下は上記の例をそのままコードに転写したJuliaのコードだ。 与えられたパラメータで、初期人口から始めてシミュレーションを1万回繰り返し、で平均を計算して理論的な予測と比較する。読みやすさを重視して書いたので、アルゴリズムが例の説明通りに実装されているかを確認しよう。
using Distributions
using Plots
b = 2.0
d = 1.0
θ = b/(b+d)
result = plot(xlims = (0,2), ylims = (0, Inf))
Y = Int64[]
@time for _ in 1:10000
y = [2]
t = [0.0]
while t[end] < 2 && y[end] > 0
push!(t, t[end] + rand(Exponential(1/((b+d) * y[end]))))
if rand() < θ
push!(y, y[end] + 1)
else
push!(y, y[end] - 1)
end
end
if t[end] > 2
push!(Y, y[end-1])
else
push!(Y, 0)
end
plot!(result, t,y, label = :none, alpha = 0.01, color = :black)
end
plot!(result, 0:0.1:2,2exp.((b-d) .* 0:0.1:2), label = :none, color = :red, linewidth = 4, linestyle = :dot)
result
abs(mean(Y) - 2exp.(2(b-d)))
実行結果を可視化すると上のようになる。理論的な予測値との差は0.1程度で、かなり正確に計算されたことが確認できる。