不均匀硬币产生等概率/均匀硬币产生非等概率

不均匀硬币产生等概率

已知随机数生成函数random(),返回0的概率是60%,返回1的概率是40%。根据random()实现一个随机数函数f(),使返回0和1的概率是50%。

连续投掷两次:
第一次为0,第二次为1:返回0
第一次为1,第二次为0:返回1

这样返回0/1的概率都是相同的。

#include <bits/stdc++.h>
using namespace std;

int main(){
    while(true){
        int a = random();
        int b = random();
        if(a== 0 && b == 1){
            cout << 1 << endl;
            break;
        }else if(a == 1 && b == 0){
            cout << 0 << endl;
            break;
        }   
    }
    return 0;
}

等概率问题还可以看看这个:LeetCode第 470 题:用 Rand7() 实现 Rand10()(C++)_zj-CSDN博客

均匀硬币产生非等概率

已知随机数生成函数random(),返回0或1的概率都是50%。根据random()实现一个随机数函数f(),使返回0的概率是30%,返回1的概率是70%。

使用二进制的思想去理解,假设现在有一位四位的二进制数(0,1表示),可能有:

0000,0001,0010,0011...1111

一共16种,表示的数字是0-15,可以认为每一位的0或1都是由random()函数生成,那么可以发现0-15之间的每一个数出现的概率都是相同的,都是1/16,表示出来就是:

random()*8 + random()*4 + random()*2 + random()*1

整体+1,就会得到1-16之前的均匀随机数。

使用拒绝采样的思路,当数字大于10的时候进行丢弃,那我们就得到了均匀的1-10之前的随机数,当数字%3 == 0的时候(3,6,9),返回0,否则返回1,这样就得到了概率0.3和0.7。

具体代码就不贴了,很简单。不过这样舍弃的数字有点多,可以多增加一位二进制位,最后得到1-30之前的随机数,思路是一样的。

猜你喜欢

转载自blog.csdn.net/qq_32523711/article/details/108940417