• 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

  • 相关阅读:
    Django之web本质
    Python之队列
    Python之阻塞IO模型与非阻塞IO模型
    *****Python之进程线程*****
    ***Python之UDP***
    Python之FTP实现
    Python之粘包
    Python之目录结构
    Python之套接字
    Linux内核分析:Linux内核启动流程分析
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/5885455.html
Copyright © 2020-2023  润新知