The Alias sample Method(复杂度为O(1)的采样算法)

原理请见:[https://www.keithschwarz.com/darts-dice-coins/]

代码运作距举例:

1.初始化

在这里插入图片描述

2.标准化(对应probs*len(probs))

在这里插入图片描述

3.将结点1切分操作到结点3(结点1,3进行pop,进行概率切分),之后结点1放入smaller

在这里插入图片描述

4.将结点0切分操作到结点2(结点0,2进行pop,进行概率切分),之后结点0放入larger

在这里插入图片描述

5.将结点0切分操作到结点1(结点0,1进行pop,进行概率切分),最终完成切分任务。

在这里插入图片描述

代码实现:

def alias_setup(probs):
    # 初始化切分标记数组J和初始概率值q
    J = np.zeros(len(probs))
    q = np.zeros(len(probs))
    smaller = []
    larger = []
    assert sum(probs) == 1.0
    # 标准化,probs = len(probs) * probs
    # 将事件分为两组,probs[i]大于1的为一组,小于一的为另一组
    for t,kk in enumerate(probs):
        q[t] = probs[t]*len(probs)
        if q[t] > 1.0:
            larger.append(t)
        else:
            smaller.append(t)
    while larger and smaller:
        large = larger.pop()
        small = smaller.pop()
        # 切大块,将小块补为1
        J[small] = large   
        q[large] = q[large] - (1 - q[small])
        if q[large] < 1.0:
            # 大块儿(大于1)变小块儿(小于1)
            smaller.append(large)
        else:
            # 大块儿依然是大块儿
            larger.append(large)
    return J,q
alias_setup([1/2,1/3,1/12,1/12])        
            

输出:
(array([0., 0., 0., 1.]),
array([1. , 0.66666667, 0.33333333, 0.33333333]))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值