【本文鏈接】
http://www.cnblogs.com/hellogiser/p/random-generator-with-equal-or-unequal-probability.html
1. 等概率生成
(1) rand5生成rand3
現在有一個Rand5函數,可以生成等概率的[0, 5)范圍內的隨機整數,要求利用此函數寫一個Rand3函數(除此之外,不能再使用任何能產生隨機數的函數或數據源),生成等概率的[0, 3)范圍內的隨機整數。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ // use rand5 to generate rand3 int Rand3() { int x; do { x = Rand5(); } while (x >= 3 ); return x; } |
(2) rand3生成rand5
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ // use rand3 to generate rand5 int Rand5() { int x; do { x = Rand3() * 3 + Rand3(); } while (x >= 5 ); return x; } |
(3) rand5生成rand7
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ // use rand5 to generate rand7 int Rand7() { int x; do { x = Rand5() * 5 + Rand5(); } while (x >= 21 ); return x % 7 ; } |
(4) rand7生成rand10
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ // use rand7 to generate rand10 int Rand10() { int x; do { x = Rand7() * 7 + Rand7(); } while (x >= 40 ); return x % 10 ; } |
(5) rand_m生成rand_n
歸納總結:將這個問題進一步抽象,已知random_m()隨機數生成器的范圍是[0, m) 求random_n()生成[0, n)范圍的函數,m < n && n <= m *m。
設t為n的最大倍數,且滿足t<m*m,即 t = ((m*m)/n)*n;
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ // use rand_m to generate rand_n int Rand_n() { int x; do { t = ((m * m) / n) * n; x = Rand_m() * m + Rand_m (); } while (x >= t); return x % n; } |
2. 不等概率生成
(1) 如何產生如下概率的隨機數?0出1次,1出現2次,2出現3次,n-1出現n次?
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ int random( int size) { while ( 1 ) { int m = rand(size); int n = rand(size); if (m + n < size) return m + n; } } |
(2) rand以不等概率生成01, 如何以1/n的等概率產生1~n之間的任意一個數?
已知隨機函數rand(),以p的概率產生0,以1-p的概率產生1,現在要求設計一個新的隨機函數newRand(),使其以1/n的等概率產生1~n之間的任意一個數。
解決思路:
可以通過已知隨機函數rand()產生等概率產生0和1的新隨機函數Rand(),然后調用k(k為整數n的二進制表示的位數)次Rand()函數,得到一個長度為k的0和1序列,以此序列所形成的整數即為1--n之間的數字。
注意:從產生序列得到的整數有可能大於n,如果大於n的話,則重新產生直至得到的整數不大於n。
第一步:由rand()函數產生Rand()函數,Rand()函數等概率產生0和1。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ int Rand() { while ( 1 ) { int i1 = rand(); int i2 = rand(); if (i1 == 0 && i2 == 1 ) return 1 ; else if (i1 == 1 && i2 == 0 ) return 0 ; } } |
第二步:計算整數n的二進制表示所擁有的位數k,k = 1 +log2n(log以2為底n)
第三步:調用k次Rand()產生隨機數,產生的k個01序列表示1-n之間的數。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ int newRand() { while ( 1 ) { int result = 0 ; for ( int i = 0 ; i < k ; ++i) { if (Rand() == 1 ) result |= ( 1 << i); } if (result <= n) return result; } } |
【本文鏈接】
http://www.cnblogs.com/hellogiser/p/random-generator-with-equal-or-unequal-probability.html