alias sample method——运行时间复杂度为O(1)的抽样算法
根据离散离散概率分布抽样是一个常见的问题。这篇文章将介绍运行时间复杂度为O(1)的 alias method 抽样算法思想。
下面举例说明:
比如 a,b,c,d 的概率分别为 0.1,0.2,0.3,0.4。如何编程实现按概率抽样呢?
最简单的方法是生成一个数组:1,2,2,3,3,3,4,4,4,4。然后随机生成一个不大于4的数。这种方法简单易实现,但当随机变量很多时,占用的空间就太大了。
再进一步,可以根据它们的概率密度分布(PDF)生成累积分布(CDF):0.1,0.3,0.6,1。然后生成不大于1的随机数,看它落在哪个区间。但这需要与临界点进行比较,
我们知道,插入有序数列最好的时间复杂度为O(logn)。
而alias method可以实现以运行复杂度为O(1)的方式抽样。当然它需要预处理,预处理的时间复杂度为O(n),但实际过程中,尤其是重复跑的时候,运行时间复杂度才是重要的。
alias method 怎么处理的呢?我们知道等概率分布抽样的时间复杂度为O(1),如果二项不等概率分布抽样的时间复杂度也为O(1)。如果a,b,c,d 概率分布均为0.25,那我们随机
生成1,2,3,4,抽中哪个就是哪个,复杂度自然为O(1)。如果只有两个变量,比如 a,b 概率分布为 0.2,0.8.那我们用CDF的方法,小于0.2就是a, 大于就是b,只需比较一次,
所以复杂度也是O(1)。alias method就是把这两种方法结合起来.
首先我们把原概率分布乘以N(为后面的拼接做准备),这里是N=4。得到:0.4,0.8,1.2,1.6。

然后我们把它拼成等概率分布和二项不等概率分布:

注意拼接的过程中,最多每一列最多有两种颜色。乘以N就保证了一定可以存在这样的拼法。具体证明见引用[1],图片出自引用[2]。
怎么抽样呢?
首先我们以等概率分布抽每一列。不失一般性,假设我们抽中了第三列。然后进行二项分布抽样,如果小于0.6,就是褐色,也就是c,反之,就是红色,也就是d.
这两个操作的复杂度均为O(1),故总时间复杂度也为O(1)。
怎么保证正确性呢?
以样本d,举例,原来抽中c的概率为0.4。运用alias method方法后,抽中c的概率为(0.25+ 0.25 * 0.2 + 0.25 * 0.4) = 0.4。事实上,等比例放大后再拆分,
其概率分布比例并没有变,结果当然也不会变。具体证明见引用[1].
引用:
1, http://www.keithschwarz.com/darts-dice-coins/
2, http://blog.csdn.net/sky_zhe/article/details/10051967
alias sample method——运行时间复杂度为O(1)的抽样算法的更多相关文章
- 时间复杂度为O(nlogn)的LIS算法
时间复杂度为 n*logn的LIS算法是用一个stack维护一个最长递增子序列 如果存在 x < y 且 a[x] > a[y],那么我们可以用a[y]去替换a[x] 因为a[y]比较小 ...
- 时间复杂度为O(nlogn)的排序算法
时间复杂度为O(nlogn)的排序算法(归并排序.快速排序),比时间复杂度O(n²)的排序算法更适合大规模数据排序. 归并排序 归并排序的核心思想 采用"分治思想",将要排序的数组 ...
- Alias sample(别名采样)
应用场景:加权采样,即按照随机事件出现的概率抽样 具体算法: 举例如上,随机事件出现的概率依次是1/2,1/3,1/12,1/12;记随机事件的个数为N,则所有事件概率乘以N后概率为2,4/3,1/3 ...
- 平均时间复杂度为O(nlogn)的排序算法
本文包括 1.快速排序 2.归并排序 3.堆排序 1.快速排序 快速排序的基本思想是:采取分而治之的思想,把大的拆分为小的,每一趟排序,把比选定值小的数字放在它的左边,比它大的值放在右边:重复以上步骤 ...
- Java虚拟机运行时数据区域及垃圾回收算法
程序计数器 记录正在执行的虚拟机字节码指令的地址(如果正在执行的是本地方法则为空). Java 虚拟机栈 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口 ...
- (转)递归算法的时间复杂度终结篇与Master method
开篇前言:为什么写这篇文章?笔者目前在学习各种各样的算法,在这个过程中,频繁地碰到到递归思想和分治思想,惊讶于这两种的思想的伟大与奇妙的同时,经常要面对的一个问题就是,对于一个给定的递归算法或者用分治 ...
- python-Day5-深入正则表达式--冒泡排序-时间复杂度 --常用模块学习:自定义模块--random模块:随机验证码--time & datetime模块
正则表达式 语法: mport re #导入模块名 p = re.compile("^[0-9]") #生成要匹配的正则对象 , ^代表从开头匹配,[0 ...
- 关于乱序(shuffle)与随机采样(sample)的一点探究
最近一个月的时间,基本上都在加班加点的写业务,在写代码的时候,也遇到了一个有趣的问题,值得记录一下. 简单来说,需求是从一个字典(python dict)中随机选出K个满足条件的key.代码如下(py ...
- java.lang.reflect.Method.getAnnotation()方法示例【通过反射获取到方法对象再获取方法对象上的注解信息】
转: java.lang.reflect.Method.getAnnotation()方法示例 java.lang.reflect.Method.getAnnotation(Class <T&g ...
随机推荐
- [流媒体]live555简介(转)
live555简介 Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.Live555实现 了对多种音视频编码 ...
- iOS 三种录制视频方式
随着每一代 iPhone 处理能力和相机硬件配置的提高,使用它来捕获视频也变得更加有意思.它们小巧,轻便,低调,而且与专业摄像机之间的差距已经变得非常小,小到在某些情况下,iPhone 可以真正替代它 ...
- acedGetString获取用户输入字符串
acedGetString()[ads_getstring()]int acedGetString(int cronly, const TCHAR *prompt, TCHAR *psz) acedG ...
- Oge中Mesh的渲染流程详述
转自:http://blog.csdn.net/yanonsoftware/article/details/1041396 首先一个Entity对象必须Attach到一个SceneNode. 1.创建 ...
- 一、XML语法
xml声明xml指令:<? ?>xml编码与乱码xml元素(标签)CDATA区空格与换行会被认为是标签的内容xml-stylesheet指令解析xml内容 <?xml version ...
- GSM BTS Hacking: 利用BladeRF和开源BTS 5搭建基站
引文 如果你已经购买了Nuand(官方)BladeRF x40,那么就可以在上面运行OpenBTS并可以输入一些指令来完成一些任务.一般来说HackRF,是一款覆盖频率最宽的SDR板卡.它几乎所有的信 ...
- struts2和servlet同时用(访问servlet时被struts2过滤器拦截问题的解决)
在同一个项目中间,如果既用到servlet有用了struts2的框架,运行项目时可能无法正常使用servlet,原因是在配置struts2的核心控制器时<url-pattern>/*< ...
- How to Write Doc Comments for the Javadoc Tool
http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html This document describe ...
- BZOJ 3782 上学路线
首先这个题需要dp.dp[i]=C(x[i]+y[i],x[i])-Σdp[j]*C(x[i]-x[j]+y[i]-y[j],x[i]-x[j])(x[i]>=x[j],y[i]>=y[j ...
- JQuery源码分析(四)
jQuery多库共存处理 多库共存换句话说可以叫无冲突处理. 总的来说会有2种情况会遇到: 1.$太火热,jQuery采用$作为命名空间,不免会与别的库框架或者插件相冲突. 2.jQuery版本更新太 ...