[0,1)区間の一様乱数から、指数分布にならう乱数を生成するには、逆関数法というのが使える。
指数分布の密度関数は、パラメータをτとすると:
$$ f(\tau)=\lambda e^{-\lambda\tau} $$
であり、分布関数 g(τ) は:
$$ g(\tau)=\int^\tau_{-\infty}{\lambda e^{-\lambda\tau}}d\tau=1-e^{-\lambda\tau} $$
となる。g(τ)は 0~1 の値をとるので、この逆関数:
$$ \tau=-\frac{1}{\lambda}log(1-g(\tau)) $$
の g(τ) の代わりに一様乱数を入力してやれば、τ は指数分布する乱数になる。
じゃあ Ruby でやってみよう。
# encoding: Windows-31J class RandExpon def initialize(lamda) @lamda = lamda @r = Random.new end def rand -1.0 / @lamda * Math.log(1 - @r.rand) end end expon = RandExpon.new(0.5) 10000.times do |i| puts expon.rand end
λ=0.5とし、10000個の乱数を発生させている。
これを Excel でグラフ化したのがこれ。
「指数分布」の曲線は、上に書いた密度関数の曲線を、スケールを合わせるために8000倍して描いている。乱数はちゃんと指数分布になっているようだ。
参考にしたページ:
cf. http://www.ishikawa-lab.com/montecarlo/4shou.html