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