美文网首页
拒绝采样算法 2021-09-05

拒绝采样算法 2021-09-05

作者: 9_SooHyun | 来源:发表于2021-09-05 23:56 被阅读0次

拒绝采样

拒绝采样就是,如果一个被采样本不满足你的需求,就放弃这个样本,重新再采一个
更一般地说,拒绝采样就是【每一次采样都存在一定概率会被舍弃并进行重新采样,从而使得采集的样本能够拟合目标概率分布】

拒绝采样,解决的问题是,通过对一个简单的概率密度分布进行选择性采样,完成对一个新的概率密度分布(往往是相对复杂的概率密度分布)的采样

一般而言,一个复杂的概率密度分布是不方便直接采样的,因为每一个样本对应的概率可能都非常杂乱无章;而在均匀分布、正态分布这些简单的概率密度分布下进行采样,则是比较容易实现的

那么,我们可以在对简单概率密度分布进行采样后,选择性地舍弃一些样本然后重新采样,从而模拟出在新的概率密度函数下的采样结果

leetcode 470. 用 Rand7() 实现 Rand10()

已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。
不要使用系统的 Math.random() 方法。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-rand10-using-rand7
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:
这个题目的本质就是基于1/7的均匀分布,生成1/10的均匀分布

拆分后放大求解

放大求解

由1/7均匀分布变换到1/6的均匀分布很简单,只要采样得到7,就舍弃这个结果再采一次,这样我们就会得到等概率的1~6

因此,由1/7均匀分布到1/n(n < 7)均匀分布是很容易的

拆分

注意到1/10可以拆解成1/2 * 1/ 5,因此我们设置两次独立采样,分别服从1/2均匀分布和1/5均匀分布,将两次采样的结果视为一次事件,就可以达到1/10均匀分布

# The rand7() API is already defined for you.
# def rand7():
# @return a random integer in the range 1 to 7

class Solution:
    def rand10(self):
        """
        :rtype: int
        """
        # 1/2均匀采样
        a = rand7()
        while a == 7:
            a = rand7()
        num = 0 if a % 2 == 0 else 5

        # 1/5均匀采样
        b = rand7()
        while b > 5:
            b = rand7()
        return num + b

缩小再放大求解

核心公式
(rand(X)-1)*Y + randY() -----生成 [1,X*Y]区间,并且等概率

这样,通过(rand7()-1)*7 + rand7() 我们就可以从1-7的随机整数扩张到1-49的随机整数,即从1/7均匀分布缩小到1/49均匀分布,而从1/49均匀分布到1/10均匀分布,就是很简单的放大求解了

# The rand7() API is already defined for you.
# def rand7():
# @return a random integer in the range 1 to 7

class Solution:
    def rand10(self):
        """
        :rtype: int
        """
        temp = (rand7() - 1) * 7 + rand7()
        while True:
            if temp > 40 :
                temp = (rand7() - 1) * 7 + rand7()
            else:
                break
        return (temp - 1) // 4 + 1

相关文章

网友评论

      本文标题:拒绝采样算法 2021-09-05

      本文链接:https://www.haomeiwen.com/subject/mwgswltx.html