首先说明下,这篇blog说的是怎么利用rand()(C++)或者Math.random()(Java)等,已有的[0,1]之间均匀分布的随机数发生器,来实现指定概率分布(比如正太分布,几何分布或者指数分布)的随机数发生器。本blog以正太分布为例,其他分布的方法类似。
定义p(t) ,为随机变量t的概率分布。P(t) 为随机变量t的累积概率。f(x) ,为正太分布的概率分布函数;F(x),为正太分布的累积概率函数。
(1)整体思路:
利用均匀分布的随机数发生器产生一个数y。y必然属于区间[0,1]。求x,使得F(x) = y。x就是要返回的随机数。
(2)证明:
这里的证明不知道会不会有问题,欢迎大牛拍砖。
这里要证明的是:F(x)属于[0,1]并p(F(x)) = 1(即F(x)是区间为[0,1]的均匀分布)。只有F(x)是区间为[0,1]的均匀分布,令F(x) = y才是合理的。
F(x),为正太分布的累积概率函数,故F(x)属于[0,1]。
令随机变量T满足分布p(F(x)),则T在[0,F(x1)]的概率分布积分,和x在[- 无穷,x1]的概率分布积分相等。P(F(x1)) = P(x1) = F(x1)。则p(F(x)) = d(P(F(x)) / d(F(x)) = d(F(x))/d(F(x)) = 1。
其他分布的证明类似。
(3)实现:
实现过程中重用性问题是值的关注的。我们在实现时,不可能把所有概率分布的都实现。这时我们希望我们的随机数发生器能方便集成用户所实现的概率分布。可以用工厂模式。工厂模式在很多地方都有介绍,这里就不多累赘了。
本blog有不足之处,欢迎指出。
最后感谢思考过程中飞哥和3D的指点。^_^。
http://blog.163.com/rustle_go_go/blog/static/202945014201211271746980/