算法用rand7()实现rand10(),拒绝采样

本文探讨了如何通过rand7函数实现不同范围的随机数生成,如如何从rand4扩展到rand10,并利用拒绝采样技巧确保结果的正确性。通过实例和代码展示了如何通过调整乘数和加法运算来调整随机数分布。

第一部分
先把问题简单化,如何利用rand2()来得到rand4()
rand2()为{1,2},最简单想法是使rand2()+rand2(),
1+1=2
1+2=3
2+1=3
2+2=4
但为了是得到随机数范围为[1,n],我们将第一个rand2()-1,得
0+1=1
0+2=2
1+1=2
1+2=3
但很容易就发现我们这样得到的结果概率不相等
此时我们尝试将rand2()-1的结果*2,得
0+1=1
0+2=3
1+1=2
2+2=4
这时结果是等概率的,但这是否是巧合?
我们再举个例子
(rand5()-1)*7+rand7()
设rand5()-1为a,rand()7为b
在这里插入图片描述
此时我们已经的到规律
(randx()-1)y+randy()可以得到[1,xy]
第二部分
那么如何通过rand4()来得到rand2(),这个就简单了,将rand4()%2+1就成了
第三部分
我们想通过rand7()来得到rand10(),我们只需用rand7()得到randN(),保证randN()>10,且为10的倍数,再用randN()%10+1,就能得到[1,10]范围的随机数.
题目中只给了rand7()
我们可得到
(rand7()-1)*7+rand7()=>rand49()
但rand49()并不是rand10()的倍数,这时我们需要拒绝采样的知识了,
也就是说,如果某个采样结果不在要求的范围内,则丢弃它.
基于上面的分析可以得到代码

class Solution extends SolBase {
    public int rand10() {
         while(true){
            int num = (rand7()-1)*7+rand7();
            if(num<=40){
              return num%10+1;
            }
        }
    }
}

文章参考leetcode大佬的分析,仅供自己学习使用,侵删
附上链接https://leetcode-cn.com/problems/implement-rand10-using-rand7/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值