1.反变换法

设需产生分布函数为F(x)的连续随机数X。若已有[0,1]区间均匀分布随机数R,则产生X的反变换公式为:

F(x)=r, 即x=F-1(r)

反函数存在条件:如果函数y=f(x)是定义域D上的单调函数,那么f(x)一定有反函数存在,且反函数一定是单调的。分布函数F(x)为是一个单调递增函数,所以其反函数存在。从直观意义上理解,因为r一一对应着x,而在[0,1]均匀分布随机数R≤r的概率P(R≤r)=r。 因此,连续随机数X≤x的概率P(X≤x)=P(R≤r)=r=F(x)

即X的分布函数为F(x)。

例子:下面的代码使用反变换法在区间[0, 6]上生成随机数,其概率密度近似为P(x)=e-x

 1 import numpy as np
 2 import matplotlib.pyplot as plt
 3
 4 # probability distribution we're trying to calculate
 5 p = lambda x: np.exp(-x)
 6
 7 # CDF of p
 8 CDF = lambda x: 1-np.exp(-x)
 9
10 # invert the CDF
11 invCDF = lambda x: -np.log(1-x)
12
13 # domain limits
14 xmin = 0 # the lower limit of our domain
15 xmax = 6 # the upper limit of our domain
16
17 # range limits
18 rmin = CDF(xmin)
19 rmax = CDF(xmax)
20
21 N = 10000 # the total of samples we wish to generate
22
23 # generate uniform samples in our range then invert the CDF
24 # to get samples of our target distribution
25 R = np.random.uniform(rmin, rmax, N)
26 X = invCDF(R)
27
28 # get the histogram info
29 hinfo = np.histogram(X,100)
30
31 # plot the histogram
32 plt.hist(X,bins=100, label=u'Samples');
33
34 # plot our (normalized) function
35 xvals=np.linspace(xmin, xmax, 1000)
36 plt.plot(xvals, hinfo[0][0]*p(xvals), 'r', label=u'p(x)')
37
38 # turn on the legend
39 plt.legend()
40 plt.show()

一般来说,直方图的外廓曲线接近于总体X的概率密度曲线。

 2.舍选抽样法(Rejection Methold)

用反变换法生成随机数时,如果求不出F-1(x)的解析形式或者F(x)就没有解析形式,则可以用F-1(x)的近似公式代替。但是由于反函数计算量较大,有时也是很不适宜的。另一种方法是由Von Neumann提出的舍选抽样法。下图中曲线w(x)为概率密度函数,按该密度函数产生随机数的方法如下:

基本的rejection methold步骤如下:

1. Draw x uniformly from [xmin  xmax]

2. Draw x uniformly from [0, ymax]

3. if y < w(x),accept the sample, otherwise reject it

4. repeat

即落在曲线w(x)和X轴所围成区域内的点接受,落在该区域外的点舍弃。

例子:下面的代码使用basic rejection sampling methold在区间[0, 10]上生成随机数,其概率密度近似为P(x)=e-x

 1 # -*- coding: utf-8 -*-
 2 '''
 3 The following code produces samples that follow the distribution P(x)=e^−x
 4 for x=[0, 10] and generates a histogram of the sampled distribution.
 5 '''
 6 import numpy as np
 7 import matplotlib.pyplot as plt
 8
 9
10 P = lambda x: np.exp(-x)
11
12 # domain limits
13 xmin = 0  # the lower limit of our domain
14 xmax = 10 # the upper limit of our domain
15
16 # range limit (supremum) for y
17 ymax = 1
18
19 N = 10000    # the total of samples we wish to generate
20 accepted = 0 # the number of accepted samples
21 samples = np.zeros(N)
22 count = 0    # the total count of proposals
23
24 # generation loop
25 while (accepted < N):
26
27     # pick a uniform number on [xmin, xmax) (e.g. 0...10)
28     x = np.random.uniform(xmin, xmax)
29
30     # pick a uniform number on [0, ymax)
31     y = np.random.uniform(0,ymax)
32
33     # Do the accept/reject comparison
34     if y < P(x):
35         samples[accepted] = x
36         accepted += 1
37
38     count +=1
39
40 print count, accepted
41
42 # get the histogram info
43 # If bins is an int, it defines the number of equal-width bins in the given range
44 (n, bins)= np.histogram(samples, bins=30) # Returns: n-The values of the histogram,n是直方图中柱子的高度
45
46 # plot the histogram
47 plt.hist(samples,bins=30,label=u'Samples')   # bins=30即直方图中有30根柱子
48
49 # plot our (normalized) function
50 xvals=np.linspace(xmin, xmax, 1000)
51 plt.plot(xvals, n[0]*P(xvals), 'r', label=u'P(x)')
52
53 # turn on the legend
54 plt.legend()
55 plt.show()

>>>

99552 10000

3.推广的舍取抽样法

从上图中可以看出,基本的rejection methold法抽样效率很低,因为随机数x和y是在区间[xmin  xmax]和区间[0  ymax]上均匀分布的,产生的大部分点不会落在w(x)曲线之下(曲线e-x的形状一边高一边低,其曲线下的面积占矩形面积的比例很小,则舍选抽样效率很低)。为了改进简单舍选抽样法的效率,可以构造一个新的密度函数q(x)(called a proposal distribution from which we can readily draw samples),使它的形状接近p(x),并选择一个常数k使得kq(x)≥w(x)对于x定义域内的值都成立。对应下图,首先从分布q(z)中生成随机数z0,然后按均匀分布从区间[0   kq(z0)]生成一个随机数u0。 if u> p(z0) then the sample is rejected,otherwise uis retained.  即下图中灰色区域内的点都要舍弃。可见,由于随机点u0只出现在曲线kq(x)之下,且在q(x)较大处出现次数较多,从而大大提高了采样效率。显然q(x)形状越接近p(x),则采样效率越高。

根据上述思想,也可以表达采样规则如下:

1. Draw x from your proposal distribution q(x)

2. Draw y uniformly from [0  1]

3. if y < p(x)/kq(x) , accept the sample, otherwise reject it

4. repeat

下面例子中选择函数p(x)=1/(x+1)作为proposal distribution,k=1。曲线1/(x+1)的形状与e-x相近。

 1 import numpy as np
 2 import matplotlib.pyplot as plt
 3
 4 p = lambda x: np.exp(-x)         # our distribution
 5 g = lambda x: 1/(x+1)            # our proposal pdf (we're choosing k to be 1)
 6 CDFg = lambda x: np.log(x +1)    # generates our proposal using inverse sampling
 7
 8 # domain limits
 9 xmin = 0  # the lower limit of our domain
10 xmax = 10 # the upper limit of our domain
11
12 # range limits for inverse sampling
13 umin = CDFg(xmin)
14 umax = CDFg(xmax)
15
16 N = 10000 # the total of samples we wish to generate
17 accepted = 0 # the number of accepted samples
18 samples = np.zeros(N)
19 count = 0 # the total count of proposals
20
21 # generation loop
22 while (accepted < N):
23
24     # Sample from g using inverse sampling
25     u = np.random.uniform(umin, umax)
26     xproposal = np.exp(u) - 1
27
28     # pick a uniform number on [0, 1)
29     y = np.random.uniform(0, 1)
30
31     # Do the accept/reject comparison
32     if y < p(xproposal)/g(xproposal):
33         samples[accepted] = xproposal
34         accepted += 1
35
36     count +=1
37
38 print count, accepted
39
40 # get the histogram info
41 hinfo = np.histogram(samples,50)
42
43 # plot the histogram
44 plt.hist(samples,bins=50, label=u'Samples');
45
46 # plot our (normalized) function
47 xvals=np.linspace(xmin, xmax, 1000)
48 plt.plot(xvals, hinfo[0][0]*p(xvals), 'r', label=u'p(x)')
49
50 # turn on the legend
51 plt.legend()
52 plt.show()

>>>

24051 10000

可以对比基本的舍取法和改进的舍取法的结果,前者产生符合要求分布的10000个随机数运算了99552步,后者运算了24051步,可以看到效率明显提高。

参考:

http://iacs-courses.seas.harvard.edu/courses/am207/blog/lecture-3.html

http://blog.csdn.net/xianlingmao/article/details/7768833

http://blog.sina.com.cn/s/blog_60b44d6a0101l45z.html

http://www.ruanyifeng.com/blog/2015/07/monte-carlo-method.html

转载于:https://www.cnblogs.com/21207-iHome/p/5266399.html

蒙特卡洛法—非均匀随机数的产生相关推荐

  1. 使用SQL生成非均匀随机数

    参考: http://www.cnblogs.com/CareySon/archive/2012/07/11/GenerateNURNsUsingSQLServer.html 正如"随机数的 ...

  2. 非均匀变异的互利自适应缎蓝园丁鸟优化算法-附代码

    非均匀变异的互利自适应缎蓝园丁鸟优化算法 文章目录 非均匀变异的互利自适应缎蓝园丁鸟优化算法 1.缎蓝园丁鸟优化算法 2.非均匀变异的互利自适应缎蓝园 2.1 非均匀变异 2.2 互利因子 2.3自适 ...

  3. 波形生成:均匀和非均匀时间向量

    波形生成-- 脉冲.chirp.VCO.正弦函数.周期性/非周期性和调制信号 使用 chirp 生成线性.二次和对数 chirp.使用 square.rectpuls 和 sawtooth 创建方波. ...

  4. NSGA-II改进之非均匀变异

    NSGA-II改进之非均匀变异 1-变异方式的选择 2-非均匀变异方式介绍 3-MATLAB代码实现 4-对比 4.1-ZDT函数比较 4.2-分析 5-总结 1-变异方式的选择 ​ 在进化算法中,多 ...

  5. 基于交叉算子和非均匀变异算子的飞蛾扑火优化算法-附代码

    基于交叉算子和非均匀变异算子的飞蛾扑火优化算法 文章目录 基于交叉算子和非均匀变异算子的飞蛾扑火优化算法 1.飞蛾扑火优化算法 2. 改进飞蛾扑火优化算法 2.1 交叉算子 2.2 非均匀变异算子 3 ...

  6. Read correction for non-uniform coverages 读校正非均匀覆盖

    下一代测序技术可以产生大量的短序列,具有广泛的应用前景.序列误差引起的噪声导致了几种校正方法的发展. 主要的校正范式期望较高的(30-40X)统一覆盖范围,以便正确地从用于校正的读操作中推断出一组参考 ...

  7. (发现)问题才是推动创新的动力系列:两种类型硬币(均匀和非均匀)能否用第一次得正面朝上的概率推断“第一第二次依次获得正面反面情况”的概率?

    两种类型硬币(均匀和非均匀)能否用第一次得正概率推断,第一第二次依次获得正反概率? 2种硬币 均匀的 COIN1  正反概率(正0.5  反0.5) 非均匀的COIN2 (正0.9  反0.1) 问题 ...

  8. ​亚马逊出品:非均匀扰动的对抗鲁棒性理论分析

    ©PaperWeekly 原创 · 作者|孙裕道 学校|北京邮电大学博士生 研究方向|GAN图像生成.情绪对抗样本生成 引言 该论文是关于对抗训练的理论性的文章.这篇论文吸引我的点在于它详细的对对抗扰 ...

  9. origin遇到不适当的参数_Origin教程|如何更改Lable和设置非均匀坐标

    有宝物的柜子 实用.有趣.干货 2019.7.7 前面,我们介绍了 Origin教程|如何改变散点图形状.颜色.大小 Origin教程|如何为数据点添加Lable和数据点值 今天分享教程 ↓↓↓ 更改 ...

最新文章

  1. 第二次作业--线性表
  2. vue中进行判断不同字段的判断,主要是区分于微信小程序和网页版之间写法
  3. php 接口说明文档,phpwind文章中心接口说明
  4. ubuntu设置root密码及 Xftp连接linux(ubuntu)时提示ssh服务器拒绝了密码,请再试一次...
  5. 【Python基础知识-pycharm版】第五节-字典\集合
  6. vue3.0生产环境和正式环境配置_vue开发环境和生产环境配置
  7. IDEA中控制台中文乱码问题
  8. PCB中 D-Subminiature(DB接口) 连接器系列分类及带有3D封装绘制
  9. DB2 数据库密码过期
  10. 自来水供水收费管理系统
  11. 自己动手 DIY 一个读写200MB/s 的高速 U 盘
  12. 【知识图谱】OpenKG开源系列 | 海洋鱼类百科知识图谱(浙江大学)
  13. 中小企业网站建设方案
  14. CollectionUtils取交集,并集和差集
  15. 打开OFFICE文件是只读属性
  16. java校园二手书交易管理系统springboot+Vue
  17. K8S部署机器学习平台
  18. miui修改Android,无法修改小米MIUI设备中的系统设置
  19. java分支结构之switch
  20. 特征值特征向量和奇异值分解精彩片段汇总

热门文章

  1. ORACLE SQL笛卡尔集
  2. DM368开发 -- uboot 使用
  3. linux不能ping通域名能ping通ip
  4. 字符在计算机中是如何表示的?
  5. 知识图谱实践篇(三):D2RQ SPARQL endpoint与两种交互方式
  6. PyTorch实战GANs
  7. Android 进程保活手段分析
  8. Android Linker学习笔记
  9. 基于Proxy思想的Android插件框架
  10. 利用xposed绕过安卓SSL证书的强校验