隨機數範圍擴展方法總結 .

 

題目:
已知有個rand7()的函數,返回1到7隨機自然數,讓利用這個rand7()構造rand10() 隨機1~10。
分析:要保證rand10()在整數1-10的均勻分佈,可以構造一個1-10*n的均勻分佈的隨機整數區間(n爲任何正整數)。假設x是這個1-10*n區間上的一個隨機整數,那麼x%10+1就是均勻分佈在1-10區間上的整數。由於(rand7()-1)*7+rand7()可以構造出均勻分佈在1-49的隨機數(原因見下面的說明),可以將41~49這樣的隨機數剔除掉,得到的數1-40仍然是均勻分佈在1-40的,這是因爲每個數都可以看成一個獨立事件。
下面說明爲什麼(rand7()-1)*7+rand7()可以構造出均勻分佈在1-49的隨機數:
首先rand7()-1得到一個離散整數集合{0,1,2,3,4,5,6},其中每個整數的出現概率都是1/7。那麼(rand7()-1)*7得到一個離散整數集合A={0,7,14,21,28,35,42},其中每個整數的出現概率也都是1/7。而rand7()得到的集合B={1,2,3,4,5,6,7}中每個整數出現的概率也是1/7。顯然集合A和B中任何兩個元素組合可以與1-49之間的一個整數一一對應,也就是說1-49之間的任何一個數,可以唯一確定A和B中兩個元素的一種組合方式,反過來也成立。由於A和B中元素可以看成是獨立事件,根據獨立事件的概率公式P(AB)=P(A)P(B),得到每個組合的概率是1/7*1/7=1/49。因此(rand7()-1)*7+rand7()生成的整數均勻分佈在1-49之間,每個數的概率都是1/49。
程序:

  1. int rand_10()  
  2. {  
  3.     int x = 0;  
  4.     do  
  5.     {  
  6.         x = 7 * (rand7() - 1) + rand7();  
  7.     }while(x > 40);  
  8.     return x % 10 + 1;  
  9. }  
int rand_10()
{
	int x = 0;
	do
	{
		x = 7 * (rand7() - 1) + rand7();
	}while(x > 40);
	return x % 10 + 1;
}
注:由朋友問爲什麼用while(x>40)而不用while(x>10)呢?原因是如果用while(x>10)則有40/49的概率需要循環while,很有可能死循環了。
問題描述
已知random3()這個隨機數產生器生成[1, 3]範圍的隨機數,請用random3()構造random5()函數,生成[1, 5]的隨機數?
問題分析
如何從[1-3]範圍的數構造更大範圍的數呢?同時滿足這個更大範圍的數出現概率是相同的,可以想到的運算包括兩種:加法和乘法
考慮下面的表達式:
3 * (random3() – 1) + random3();
可以計算得到上述表達式的範圍是[1, 9]  而且數的出現概率是相同的,即1/9
下面考慮如何從[1, 9]範圍的數生成[1, 5]的數呢?
可以想到的方法就是 rejection sampling 方法,即生成[1, 9]的隨機數,如果數的範圍不在[1, 5]內,則重新取樣
解決方法

  1. int random5()  
  2. {  
  3.     int val = 0;  
  4.     do  
  5.     {  
  6.         val = 3 * (random3() - 1) + random3();  
  7.     }while(val > 5);  
  8.     return val;  
  9. }  
int random5()
{
	int val = 0;
	do
	{
		val = 3 * (random3() - 1) + random3();
	}while(val > 5);
	return val;
}
歸納總結
將這個問題進一步抽象,已知random_m()隨機數生成器的範圍是[1, m] 求random_n()生成[1, n]範圍的函數,m < n && n <= m *m
一般解法:

  1. int random_n()  
  2. {  
  3.     int val = 0;  
  4.     int t;   //t爲n的最大倍數,且滿足t<m*m   
  5.     do  
  6.     {  
  7.         val = m * (random_m() - 1) + random_m();  
  8.     }while(val > t);  
  9.     return val;  
  10. }  

轉自:http://blog.csdn.net/hackbuteer1/article/details/7486704

發佈了32 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章