等概率隨機函式的實現

2021-06-18 08:26:00 字數 1786 閱讀 5644

題目:已知隨機函式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。

[cpp]view plain

copy

int rand()    

第二步:計算整數n的二進位制表示所擁有的位數k,k = 1 +log2n(log以2為底n)

第三步:呼叫k次rand()產生隨機數。

[cpp]view plain

copy

int newrand()  

if(result > n)  

return newrand();  

return result;  

}  

題目:給定乙個函式rand5(),該函式可以隨機生成1-5的整數,且生成概率一樣。現要求使用該函式建構函式rand7(),使函式rand7()可以隨機等概率的生成1-7的整數。

思路:很多人的第一反應是利用rand5() + rand()%3來實現rand7()函式,這個方法確實可以產生1-7之間的隨機數,但是仔細想想可以發現數字生成的概率是不相等的。rand()%3 產生0的概率是1/5,而產生1和2的概率都是2/5,所以這個方法產生6和7的概率大於產生5的概率。

正確的方法是利用rand5()函式生成1-25之間的數字,然後將其中的1-21對映成1-7,丟棄22-25。例如生成(1,1),(1,2),(1,3),則看成rand7()中的1,如果出現剩下的4種,則丟棄重新生成。

簡單實現:

[cpp]view plain

copy

int rand7()  

while(x > 21);  

return 1 + x%7;  

}  

我的備註:

這種思想是基於,rand()產生[0,n-1],把rand()視為n進製的一位數產生器,那麼可以使用rand()*n+rand()來產生2位的n進製數,以此類推,可以產生3位,4位,5位...的n進製數。這種按構造n進製數的方式生成的隨機數,必定能保證隨機,而相反,借助其他方式來使用rand()產生隨機數(如 rand5() + rand()%3 )都是不能保證概率平均的。

此題中n為5,因此可以使用rand5()*5+rand5()來產生2位的5進製數,範圍就是1到25。再去掉22-25,剩餘的除3,以此作為rand7()的產生器。

給定乙個函式rand()能產生0到n-1之間的等概率隨機數,問如何產生0到m-1之間等概率的隨機數?

[cpp]view plain

copy

int random(int m , int n)  

return k/(max/n);  

}  

如何產生如下概率的隨機數?0出1次,1出現2次,2出現3次,n-1出現n次?

[cpp]view plain

copy

int random(int size)  

等概率隨機函式的實現

題目 已知隨機函式rand 以p的概率產生0,以1 p的概率產生1,現在要求設計乙個新的隨機函式newrand 使其以1 n的等概率產生1 n之間的任意乙個數。解決思路 可以通過已知隨機函式rand 產生等概率產生0和1的新隨機函式rand 然後呼叫k k為整數n的二進位制表示的位數 次rand 函...

等概率隨機函式的實現

解決思路 可以通過已知隨機函式rand 產生等概率產生0和1的新隨機函式rand 然後呼叫k k為整數n的二進位制表示的位數 次rand 函式,得到乙個長度為k的0和1序列,以此序列所形成的整數即為1 n之間的數字。注意 從產生序列得到的整數有可能大於n,如果大於n的話,則重新產生直至得到的整數不大...

非等概率隨機演算法

自己做了乙個非等概率的隨機演算法的封裝,然後後面人的可以借用。probability是概率,最好是兩位小數,然後返回1的概率是probability,返回0的概率是1 probability 如果是三元組或者是多元組,多返回幾個值就可以了 int notequalprobability float ...