1. 程式人生 > >如何用均勻分佈隨機數生成正態分佈隨機數

如何用均勻分佈隨機數生成正態分佈隨機數

前言

在Monte Carlo模擬技術中,許多地方都需要用到符合標準正態分佈(高斯)的隨機數來設計取樣方案,因此瞭解如何用均勻分佈隨機數(實際上是均勻分佈的偽隨機數)來生成標準正態分佈的隨機數十分重要。本文將對這個最基本的問題做討論,並提供c++11程式碼。

在討論更高效的演算法之前,我們先來看看能不能基於中心極限定理來設計演算法。中心極限定理告訴我們,對於一組i.i.d的隨機數{xk}U(μ,σ2),有1ni=1nxiN(μ,σ2/n)。這個演算法有兩個問題:
1. 計算量大。生成一個數需要用n個均勻分佈隨機數。
2. 無法準確刻畫正態分佈的末端效應。生成的數均有界,不會是很大的數。

此外,如果用“拒絕取樣(rejection sampling)“的思路,在覆蓋f(x)=cex2/2的矩形內均勻投點,保留曲線下的點,則計算較複雜(exp函式),而且捨棄點多代價大。

我們下面介紹兩種更高效的演算法:The Box–Muller transform 和 The Ziggurat algorithm。它們一個是對分佈函式做了變換,另一個還是使用了“拒絕取樣“的思路,但並不是簡單的僅用一個大矩形覆蓋。

The Box–Muller transform

The Box–Muller transform 把一對均勻分佈隨機數對映到一對標準正態分佈隨機數。它有兩種形式:
1. 基本形式:用

(0,1)均勻分佈隨機數,需要計算三角函式sincos
2. 極座標形式:用(1,1)均勻分佈隨機數,且不需要計算三角函式。

我們希望計算積分I=ex2/2dx,可以先取它的平方並用極座標表示,

I2=e(x2+y2)/2dxdy=02π0rer2/2drdθ.可以看到極角θ服從(0,2π)均勻分佈,徑向距離r服從rer2/2分佈函式(即r2服從χ2)。如果把r的累積分佈函式(cumulative distribution function)寫出來
F(x)=0xrer2/2dr=1ex2/2,
我們就可以通過F的逆函式F1(u),將均勻分佈uU(0,1)對映到目標分佈,即