1. 程式人生 > >淺析 rand7生成rand10 方法 之 思想篇(一)

淺析 rand7生成rand10 方法 之 思想篇(一)

同余 one a + b 個數 height 意義 UC ogr edi

【問題描寫敘述】

rand7是一個能生成1-7的隨機數。要求利用rand7生成1-10的隨機數。

【算法思想】

1.組合數學方法
第1次 1 2 3 4 5 6 7 之中用rand7取一個數
第2次從 2 3 4 5 6 7 8 之中取一個數
第3次從 3 4 5 6 7 8 9 之中取一個數
第4次從 4 5 6 7 8 9 10 之中取一個數
第5次從 5 6 7 8 9 10 1 之中取一個數
第6次從 6 7 8 9 10 1 2 之中取一個數
...
第10次從 10 1 2 3 4 5 6 之中用取一個數
1-10每一個數字在上表中都出現了7次。共同擁有70個數字,這樣每一個數字被命中的概率為1/10。
這裏的關鍵詞是"命中".
第11次又一次循環,從 1 2 3 4 5 6 7 之中取一個數
第12次從 2 3 4 5 6 7 8 之中取一個數
......
依照這種方法。1-10每一個數字被命中的概率是均勻分布。而1-10次的數組,本質上是生成了全部1-10依照次序的一個輪換結構。也就是組合問題中的生成全部排列。(參見Knuth第4卷第2冊(The Art Of Computer Programming, Volume4, Generating All Tuples and Permutations))在經過比較長的時間之後,就能夠觀察到均勻分布。其實,不論什麽隨機數算法都須要經過比較長的過程才幹觀察出他的分布。而概率分布。是在一個統計意義上的概念。
由此還能夠得出用m個隨機數生成n個隨機數的方法
1. 當m > n的時候,用舍去法,每次n個隨機數,超過這個範圍就舍棄,再來一次。
2. 當m < n的時候,用如上的方法建立m大小的數組,當中的數字在1到n依照次序循環輪換,這樣n*m個循環之後。就能夠得到均勻的n個隨機數。



2. 同余循環法
上面這種方法。實際上等價於(rand7() + i)%10。i從0-9重復循環。而每次計算的余數恰好與上面的方法等價。也就是用利用同余的性質生成全部排列。這真是一個巧妙的想法!

於是:
1. i從0到9重復循環
2. (rand7()+i)%10,產生0-9的隨機數。等效與第一種組合法(僅僅須要把上面表中的1-10改成0-9)

3. 再+1得到1-10的隨機數
優化後僅僅須要一行代碼!


於是上面用m個隨機數生成n個隨機數的方法的,也有了更簡潔的算法,步驟與此相似就不寫了。


3. 舍去法

這個題在考試中大概是不讓用舍去法的,由於他太平庸。

但實際上舍入法也非常實用。因此還是寫出來,後面還會再提到舍入法。


1. 第一次用rand7取出1到5的隨機數,記為a
2. 第二次用rand7取出1或2,記為b
3. 假設b = 1, 則c = a, 假設b = 2,則c = a + b
4. 返回c

4. . 連續隨機變量的分布
本題的rand7是一個離散隨機變量,僅僅取1-7的整數。

離散變量的缺點是在數學計算上不方便,因此能夠轉成連續隨機變量。也就是從rand7生成1-7的連續均勻分布,獲得1-10的均勻分布。盡管本題不適用這種方法,可是本題除了考試實用,在實際應用中不會出現,很多其它的方法是從一種分布變換到第二種分布。


如今的答案非常easy。從幾何的角度上看,我們能夠把[a,b]線段上的點依照一對一映射到還有一個線段[c,d]上去,僅僅須要做一個線性變換y=(x-a)/(b-a)*(d-c)+c. 那麽。若rand()~U(a,b),則y=(rand()-a)/(b-a)*(d-c)+c~U(c,d)。也就是假設rand()是a到b上的均勻分布,則y=(d-c)(x-a)/(b-a)+c是c到d上的均勻分布。

對於本例rand10=(rand()-1)/6*9+1.?
這個定理還能夠更強一些,f(x)是分段還是也能夠。甚至僅僅是一個覆蓋(包含)就能夠了。從符合一種分布的隨機數生成第二種分布的隨機數是統計模擬的課題,當中有非常有趣的變換方法,比如,假設X是(0,1)上的均勻分布,則Y=-a*log(X)是指數分布。這些內容,參考《統計判斷》,或者更進一步的材料。



5. 再談舍入法
C語言的rand函數,可能是用了線性同余算法獲得均勻分布,這類叫直接方法。舍去法也是非常重要的一類隨機,用來生成各種分布的隨機數,比方Metropolis算法。比較著名的還有Markov Chain Monte Carlo (MCMC)算法。這類方法能夠看成是一個黑盒子。要求在算法內部通過幾次運算非常快收斂到一種概率分布,然後返回一個隨機數。參見Casella & Berger統計判斷(Statistical Inference)以及Kunth第2卷Seminumerical Algorithms, Random Numbers.

淺析 rand7生成rand10 方法 之 思想篇(一)