拒绝采样(算法)总结

        先说说什么是拒绝采样算法:就类似于数学上的求阴影面积的方法,直接求求不出来,就用大面积 - 小面积 = 阴影面积的办法。

        所谓拒绝 和 采样 :就像是撒豆子计个数,计算概率问题一样,大桶里面套小桶,一把豆子撒下去,每个豆子都是一个“样本”,如果落在小桶外面的大桶里面去了,就“拒绝”这个样本,如果在小桶里,就“采用”这个样本, 就这样拒绝-和采用所有的豆子,小桶里面的豆子数量除以所有的豆子的数量就得到啊小桶在大桶里的占比,也就是豆子落在小桶里的概率……………………巴拉巴拉一些关于概率的问题就可以这样求解了。

这是力扣的两题,一一举例加以解释。

读题:现在有一个只能生成1、2、3、4、5、6、7这7个数字的随机函数Rand7(),问你如何用这个函数实现一个可以随机生成1~10的随机函数Rand10()(PS:随机函数,生成其中每个值的概率必须相等才行

想法:想想二进制(011010010111000010101010)这玩意,用两个Rand7()就可以生成7*7=49种选择,我们只要10种就够了,所以可以有

1和1、1和2、1和3   表示 1

1和4、1和5、1和6  表示  2

2和1、2和2、2和3   表示 3

2和4、2和5、2和6  表示  4

3和1、3和2、3和3   表示 5

3和4、3和5、3和6  表示  6

4和1、4和2、4和3   表示 7

4和4、4和5、4和6  表示  8

5和1、5和2、5和3   表示 9

5和4、5和5、5和6  表示  10

6和1、6和2、6和3   (拒绝表示)

6和4、6和5、6和6   (拒绝表示)

7和1、7和2、7和3   (拒绝表示)

7和4、7和5、7和6   (拒绝表示)

也就是:第一个Rand7() 只能生成1~5中的一个数,第二个Rand7()只能生成1~6中的一个数,不然就拒绝采样,重新生成才行。

代码:(优化前)

class Solution {
public:
    int rand10() {
        int a,b;
        while(1){
            a = rand7();
            if( a != 6 && a != 7 ) break;
        }
        while(1){
           b = rand7();
           if( b != 7 ) break;
        }
        if( a == 1 ){
            if( b <= 3 ) return 1;
            else return 2;
        }
        else if( a == 2 ){
            if( b <= 3 ) return 3;
            else return 4;
        }
        else if( a == 3 ){
            if( b <= 3 ) return 5;
            else return 6;
        }
        else if( a == 4 ){
            if( b <= 3 ) return 7;
            else return 8;
        }
        else {
            if( b <= 3 ) return 9;
            else return 10;
        }
    }
};

代码:(优化后)

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

不懂??????????没关系,看第二个,更简单!!!!!!!!!!!!!!!!!

第二题(别看题目,看下面读题

读题:给一个半径 r0 和圆心坐标 x0, y0 ; 然后返回这个圆上或者圆内随机一点的坐标值(注:全是double类型,而且落在每一点上的概率必须相等

官解:两个随机函数呗,一个随机范围是 [ x0-r0, x0+r0 ] ,另一个是[ y0-r0, y0+r0 ], 只要两个随机数的平方和大于了半径 r0 就统统 “拒绝”,只计算 平方和小于半径的结果,看图: 

(这官解太low了)

这不就是撒豆子算概率问题嘛,随机生成的坐标点 x , y 就豆子的落点,这个落点只能在圆内,如果在圆外了就“拒绝”这个坐标,给我重新生成去。

(单纯是为了说明拒绝采样算法而已,此题有更佳的解法)

// 作者:力扣官方题解
class Solution {
private:
    mt19937 gen{random_device{}()};
    uniform_real_distribution<double> dis;
    double xc, yc, r;

public:
    Solution(double radius, double x_center, double y_center): dis(-radius, radius), xc(x_center), yc(y_center), r(radius) {}
    
    vector<double> randPoint() {
        while (true) {
            double x = dis(gen), y = dis(gen);
            if (x * x + y * y <= r * r) {
                return {xc + x, yc + y};
            }
        }
    }
};

最有解法:(极坐标法)

 (这字丑自己都不想看)

代码:(并没有用拒绝采样算法,但是效率上是它的两倍,拒绝采样要170ms+,但是极坐标只需要80ms)

class Solution {
private:
    double rc,xc,yc;
public:
    Solution(double radius, double x_center, double y_center) {
        rc = radius;
        xc = x_center;
        yc = y_center;
    }
    
    vector<double> randPoint() {
        double Rx = rc * sqrt( (double)rand()/RAND_MAX );
        double angle = 2 * M_PI * (double)rand()/RAND_MAX;
        return { xc + Rx*cos(angle), yc + Rx*sin(angle)};
    }
};

相关推荐

  1. 简历总结:打造HR无法拒绝的简历

    2024-01-01 16:44:01       12 阅读
  2. 音频重采样算法

    2024-01-01 16:44:01       14 阅读
  3. 固定数量点云采样算法

    2024-01-01 16:44:01       8 阅读
  4. 拒绝拖延。

    2024-01-01 16:44:01       12 阅读
  5. 贪心算法总结

    2024-01-01 16:44:01       40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-01 16:44:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-01 16:44:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-01 16:44:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-01 16:44:01       20 阅读

热门阅读

  1. Go语言程序设计-第6章--方法

    2024-01-01 16:44:01       38 阅读
  2. Linux常见的21条面试命令

    2024-01-01 16:44:01       33 阅读
  3. 深入理解和运用C语言中的Break语句

    2024-01-01 16:44:01       37 阅读
  4. 编码风格之(1)C语言建议规范

    2024-01-01 16:44:01       41 阅读
  5. Docker常用命令

    2024-01-01 16:44:01       39 阅读
  6. 用指针实现冒泡排序

    2024-01-01 16:44:01       36 阅读
  7. 【Vue3】请求参数

    2024-01-01 16:44:01       37 阅读
  8. 牛客小白月赛84

    2024-01-01 16:44:01       29 阅读
  9. Android学习记录(二)

    2024-01-01 16:44:01       39 阅读
  10. 【Python 千题 —— 基础篇】句子单词小写

    2024-01-01 16:44:01       34 阅读