java生成指数分布随机数_生成特定分布随机数的方法
生成隨機數(shù)是程序設計里常見的需求。一般的編程語言都會自帶一個隨機數(shù)生成函數(shù),用于生成服從均勻分布的隨機數(shù)。不過有時需要生成服從其它分布的隨機數(shù),例如高斯分布或指數(shù)分布等。有些編程語言已經(jīng)有比較完善的實現(xiàn),例如Python的NumPy。這篇文章介紹如何通過均勻分布隨機數(shù)生成函數(shù)生成符合特定概率分布的隨機數(shù),主要介紹Inverse Ttransform和Acceptance-Rejection兩種基礎算法以及一些相關的衍生方法。下文我們均假設已經(jīng)擁有一個可以生成0到1之間均勻分布的隨機數(shù)生成函數(shù),關于如何生成均勻分布等更底層的隨機數(shù)生成理論,請參考其它資料,本文不做討論。
基礎算法
Inverse Transform Method
最簡單的生成算法是Inverse Transform Method(下文簡稱ITM)。如果我們可以給出概率分布的累積分布函數(shù)(下文簡稱CDF)及其逆函數(shù)的解析表達式,則可以非常簡單便捷的生成指定分布隨機數(shù)。
ITM算法描述
生成一個服從均勻分布的隨機數(shù)U~Uni(0,1)
設F(X)為指定分布的CDF,F?1(Y)是其逆函數(shù)。返回X=F?1(U)作為結果
ITM算法說明
這是一個非常簡潔高效的算法,下面說明其原理及正確性。
我們通過圖示可以更直觀的明白算法的原理。下圖是某概率分布的CDF:
我們從橫軸上標注兩點xa和xb,其CDF值分別為F(xa)和F(xb)。
由于U服從0到1之間的均勻分布,因此對于一次U的取樣,U落入F(xa)和F(xb)之間的概率為:
而由于CDF都是單調(diào)非減函數(shù),因此這個概率同時等于X落入xa和xb之間的概率,即:
而根據(jù)CDF的定義,這剛好說明XX服從以F(x)為CDF的分布,因此我們的生成算法是正確的。
ITM實現(xiàn)示例
下面以指數(shù)分布為例說明如何應用ITM。
首先我們需要求解CDF的逆函數(shù)。我們知道指數(shù)分布的CDF為
通過簡單的代數(shù)運算,可以得到其逆函數(shù)為
由于UU服從從0到1的均勻分布蘊含著1?U服從同樣的分布,因此在實際實現(xiàn)時可以用Y代替1?Y,得到:
下面給出一個Python的實現(xiàn)示例程序。
importrandom
importmath
defexponential_rand(lam):
iflam?<=0:
return-1
U?=random.uniform(0.0,1.0)
return(-1.0/lam)*math.log(U)
Acceptance-Rejection Method
一般來說ITM是一種很好的算法,簡單且高效,如果可以使用的話,是第一選擇。但是ITM有自身的局限性,就是要求必須能給出CDF逆函數(shù)的解析表達式,有些時候要做到這點比較困難,這限制了ITM的適用范圍。
當無法給出CDF逆函數(shù)的解析表達式時,Acceptance-Rejection Method(下文簡稱ARM)是另外的選擇。ARM的適用范圍比ITM要大,只要給出概率密度函數(shù)(下文簡稱PDF)的解析表達式即可,而大多數(shù)常用分布的PDF是可以查到的。
ARM算法描述
設PDF為f(x)f(x)。首先生成一個均勻分布隨機數(shù)X~Uni(xmin,xmax)
獨立的生成另一個均勻分布隨機數(shù)Y~Uni(ymin,ymax)
如果Y≤f(X),則返回X,否則回到第1步
ARM算法說明
通過一幅圖可以清楚的看到ARM的工作原理。
ARM本質(zhì)上是一種模擬方法,而非直接數(shù)學方法。它每次生成新的隨機數(shù)后,通過另一個隨機數(shù)來保證其被接受概率服從指定的PDF。
顯然ARM從效率上不如ITM,但是其適應性更廣,在無法得到CDF的逆函數(shù)時,ARM是不錯的選擇。
ARM實現(xiàn)示例
下面使用ARM實現(xiàn)一個能產(chǎn)生標準正態(tài)分布的隨機數(shù)生成函數(shù)。
首先我們要得到標準正態(tài)分布的PDF,其數(shù)學表示為:
為了方便,這里我會直接使用SciPy來計算其PDF。
程序如下。
importrandom
importscipy.stats?asss
defstandard_normal_rand():
whileTrue:
X?=random.uniform(-3.0,3.0)
Y?=random.uniform(0.0,0.5)
ifY?
returnX
注意:標準正態(tài)分布的x取值范圍從理論上說是(?∞,∞),但是當離開均值點很遠后,其概率密度可忽略不計。這里只取(?3.0,3.0),實際使用時可以根據(jù)具體需要擴大這個取值范圍。
衍生算法
組合算法
當目標分布可以用其它分布經(jīng)過四則運算表示時,可以使用組合算法生成對應隨機數(shù)。
最常見的就是某分布可以表示成多個獨立同分布(下文簡稱IID)隨機變量之和。例如二項分布可以表示成多個0-1分布之和,Erlang分布可以由多個IID的指數(shù)分布得出。
以Erlang分布為例說明如何生成這類隨機數(shù)。
設X1,X2,?,Xk為服從0到1均勻分布的IID隨機數(shù),則
為服從指數(shù)分布的IID隨機數(shù),因此
所以生成Erlang分布隨機數(shù)的算法如下:
這類分布的隨機數(shù)生成算法很直觀,就是先生成相關的n個IID隨機數(shù),然后帶入簡單求和公式或其它四則公式得出最終隨機數(shù)。其數(shù)學理論基礎是卷積理論,稍微有些復雜,這里不再討論,有興趣的同學可以查閱相關資料。
生成具有相關性的隨機數(shù)
現(xiàn)在考慮生成多維隨機數(shù),以最簡單的二維隨機數(shù)為例。
如果兩個維度的隨機數(shù)是相互獨立的,那么只要分別生成兩個列就可以了。但是如果要求兩列具有一定的相關系數(shù),則需要做一些特殊處理。
下列算法可以生成兩列具有相關系數(shù)ρ的隨機數(shù)。
生成IID隨機變量X和Y
計算
返回(X,X′)
可以這樣驗證其正確性:
注意:
因此X和X′確實具有相關系數(shù)ρ。
更多參考
這篇文章討論了生成指定分布隨機數(shù)的基本方法。這篇文章只打算討論基礎方法,所以還有很多有趣的內(nèi)容,本文沒有深入的探討。這里給出一些擴展閱讀資料,供有興趣的朋友深入學習。首先是一篇非常好的文檔,這篇文章來自美國陸軍實驗室,對計算機生成指定分布隨機數(shù)的方方面面進行了全面深入描述,是不可多得的好資料。
在實現(xiàn)方面,可以參考NumPy中關于random的實現(xiàn)以及我開發(fā)的JavaScript實現(xiàn)。另外我做過一個不同概率分布的可視化頁面,可以幫助你直觀理解不同分布及PDF參數(shù)對分布的影響。
總結
以上是生活随笔為你收集整理的java生成指数分布随机数_生成特定分布随机数的方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python巴特沃斯滤波器_butter
- 下一篇: 淘宝API开发系列:淘宝图片搜索API