拒绝采样 Rejection Sampling

2018-12-09 16:40:30

一、使用Rand7()来生成Rand10()

问题描述:

问题求解:

这个问题字节跳动算法岗面试有问到类似的,有rand6,求rand8,我想了好久,最后给了一个特殊解法,就进行三次,每次取前三个数和后三个数的概率相等为1 / 2,那么最后需要得到的概率是1 / 8,就可以通过取三次得到。问题就转变成了映射的问题,当然映射的方式是很简单的,类似二进制的方法,很容易就可以进行映射。

但是,上述的解法在本题中是没有办法使用的,就需要更通用的解法,说实话,之前也没有做过Rejection Sampling标签下的题目,这个问题的通用解法就是使用拒绝采样的算法来进行解决。

首先我们肯定是需要对原空间进行扩充的,因为原空间的大小比生成空间的大小要小。

我其实最初想到的也是两次求rand7(),然后直接求和,但是很显然的这样得到的解空间中的1 - 10是不平均分配的,即使通过对10取余 + 1也不能得到等概率的解。

当然还有人可能会想通过求乘积的方式来扩充空间,可惜的是这样也是非等概率的,具体可以见下图:

那么怎么样才能得到等概率的呢?其实,我们只需要对两次取得的各个可能的数进行编号,每个编号不就是等可能的么?

由于编号的总长度大于10的倍数,后面的49 - 40 = 9个数字就需要抛弃掉。通过这种方式,我们就可以等概率的生成1 - 10这10个整数。

/**
 * The rand7() API is already defined in the parent class SolBase.
 * public int rand7();
 * @return a random integer in the range 1 to 7
 */
class Solution extends SolBase {
    public int rand10() {
        int res = Integer.MAX_VALUE;
        while (res >= 40) {
            res = 7 * (rand7() - 1) + rand7() - 1;
        }
        return res % 10 + 1;
    }
}

二、Generate Random Point in a Circle

问题描述:

问题求解:

本题最直观的解法就是拒绝采样了,解法的流程是生成一个圆的外接矩形框,随机产生矩形框中的数字,如果在圆内,那么就输出,否则拒绝采样,重新生成一遍。

本题中有个问题就是题目描述中说边界的点是算在圆中的,但是Java中的随机数如Math.random(),或者Random rand.nextDouble()产生的随机数都在[0, 1.0)前开后闭,这也就意味着某些圆上的点是没有办法取到的。

这个问题呢,可以这么理解,纵然有某些圆上的点是没有办法取到的,但是并不影响最终的结果,因为圆中的点理论上来说是有无数个的,因此对于某个单独的点其生成的概率是为0 的。

class Solution {
    double r, x, y;

    public Solution(double radius, double x_center, double y_center) {
        r = radius;
        x = x_center;
        y = y_center;
    }

    public double[] randPoint() {
        Random rand = new Random();
        Double nx = x - r + rand.nextDouble() * 2 * r;
        double ny = y - r + rand.nextDouble() * 2 * r;
        double r2 = r * r;
        while(dis(nx, ny) >= r2){
            nx = x - r + rand.nextDouble() * 2 * r;
            ny = y - r + rand.nextDouble() * 2 * r;
        }
        return new double[]{nx, ny};
    }

    // it returns the square of the distance between the point and the center;
    double dis(double nx, double ny){
        return (nx - x) * (nx - x) + (ny - y) * (ny - y);
    }
}

原文地址:https://www.cnblogs.com/TIMHY/p/10091978.html

时间: 2024-08-30 07:32:55

拒绝采样 Rejection Sampling的相关文章

470. Implement Rand10() Using Rand7() (拒绝采样Reject Sampling)

问题 已提供一个Rand7()的API可以随机生成1到7的数字,使用Rand7实现Rand10,Rand10可以随机生成1到10的数字. 思路 简单说: (1)通过(Rand N - 1) % 10 + 1的方法,可以求出Rand10,当N是10的倍数的时候. (2)用( Rand7 - 1 ) * 7 + Rand7可以随机生成1-49,记作Rand49. (3)如果可以通过Rand49计算出Rand40,即随机生成1-40,就可以通过Rand40 % 10来取得Rand10. (4)如何通过

蒙特卡洛采样之拒绝采样(Reject Sampling)

引子 蒙特卡洛(Monte Carlo)方法是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为基础的数值计算方法.它的核心思想就是使用随机数(或更常见的伪随机数)来解决一些复杂的计算问题. 当所求解问题可以转化为某种随机分布的特征数(比如随机事件出现的概率,或者随机变量的期望值等)时,往往就可以考虑使用蒙特卡洛方法.通过随机抽样的方法,以随机事件出现的频率估计其概率,或者以抽样的数字特征估算随机变量的数字特征,并将其作为问题的解.这种方法多用于求解复杂的高

漫谈“采样”(sampling)

??越学越懵了,计算机中是怎么进行采样的,用了这么久的 rand() 函数,到现在才知道是怎么做的. 从均匀分布中采样 ??计算机中通过线性同余发生器(linear congruential generator,LCG)很容易从一个 $ x \sim Uniform[0, 1)$ 的均匀分布中进行采样.如果要从 \(y \sim Uniform[a, b)\) 的均匀分布中采样,只需要 \(x\) 的基础上做个变换 \(y = (b-a)x + a\) 即可. ??当然除了 LCG 外,还有其它

随机采样和随机模拟:吉布斯采样Gibbs Sampling的具体实现

http://blog.csdn.net/pipisorry/article/details/51525308 吉布斯采样的实现问题 本文主要说明如何通过吉布斯采样进行文档分类(聚类),当然更复杂的实现可以看看吉布斯采样是如何采样LDA主题分布的[主题模型TopicModel:隐含狄利克雷分布LDA]. 关于吉布斯采样的介绍文章都停止在吉布斯采样的详细描述上,如随机采样和随机模拟:吉布斯采样Gibbs Sampling(why)但并没有说明吉布斯采样到底如何实现的(how)? 也就是具体怎么实现

随机采样和随机模拟:吉布斯采样Gibbs Sampling

http://blog.csdn.net/pipisorry/article/details/51373090 马氏链收敛定理 马氏链定理: 如果一个非周期马氏链具有转移概率矩阵P,且它的任何两个状态是连通的,那么limn→∞Pnij 存在且与i无关,记limn→∞Pnij=π(j), 我们有 limn→∞Pn=???????π(1)π(1)?π(1)?π(2)π(2)?π(2)??????π(j)π(j)?π(j)????????????? π(j)=∑i=0∞π(i)Pij π 是方程 πP

使用MATLAB贝叶斯工具箱(BNT),进行吉布斯采样(Gibbs Sampling)之前需要做的编译工作

使用BNT(Bayesian Networks Toolbox)进行推断时,内置了吉布斯采样算法(即gibbs_sampling_inf_engine),但是如果调用这个引擎做推断会报错.报错内容大概是compute_posterior这个函数没有找到,然后进入..\@gibbs_sampling_inf_engine\private这个目录可以发现一个叫compute_posterior.c的文件,并没有.m文件,MATLAB当然不能调用C语言文件,所以需要对C文件进行编译,编译成为MATLA

转 如何理解 重要性采样(importance sampling)

分类: 我叫学术帖2011-03-25 13:22 3232人阅读 评论(4) 收藏 举报 图形 重要性采样是非常有意 思的一个方法.我们首先需要明确,这个方法是基于采样的,也就是基于所谓的蒙特卡洛法(Monte Carlo).蒙特卡洛法,本身是一个利用随机采样对一个目标函数做近似.例如求一个稀奇古怪的形状的面积,如果我们没有一个解析的表达方法,那么怎么做 呢?蒙特卡洛法告诉我们,你只要均匀的在一个包裹了这个形状的范围内随机撒点,并统计点在图形内的个数,那么当你撒的点很多的时候,面积可以近似为=

拒绝采样

470. 用 Rand7() 实现 Rand10() 难度中等55收藏分享切换为英文关注反馈 已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数. 不要使用系统的 Math.random() 方法. 示例 1: 输入: 1 输出: [7] 示例 2: 输入: 2 输出: [8,4] 示例 3: 输入: 3 输出: [8,1,10] 提示: rand7 已定义. 传入参数: n 表示 rand10 的调用次数. 进阶

逆变换采样

逆变换采样(英语:inverse transform sampling),又称为逆采样(inversion sampling).逆概率积分变换(inverse probability integral transform).逆变换法(inverse transformation method).斯米尔诺夫变换(Smirnov transform).黄金法则(golden rule)等,是伪随机数采样的一种基本方法.在已知任意概率分布的累积分布函数时,可用于从该分布中生成随机样本. Inverse