我有每个值的值和相关概率的集合(所有积极的,但远非相等)。我想多次从这个发行版中抽样。一种技术上正确的方法是线性搜索,如下所示:
def sample(xs,ps,p):
for i in xrange(len(ps)):
if ps[i] <= p: return xs[i]
用Python表示法。然后进行采样,你需要p = random.random()。如果xs和ps非常大,这种线性搜索方法非常慢。因此,我想按照二分搜索的方式做一些事情。我的第一个想法是构建一个二叉树,并通过使用随机位序列遍历树进行采样(如果位为零则向左,如果为1则向右)。我将通过以类似于快速排序的方式拆分概率累积和的列表来构建树:树的左侧部分是值&lt; = 1/2,树的右侧部分是值&gt; 1 / 2,然后我递归,以便树的LL部分是值&lt; = 1/4,LR部分是值> 1/4但<&lt; = 1/2等等。
我确实在玩具示例中实现了这一点,其中概率的累积总和为[0.26,0.91,0.99,1]。 (所以26%的时间你得到第一个值,65%的时间得到第二个值,8%得到第三个值,1%得到最后一个值)。
我结束了两个问题。我已经修复了一个问题:某些节点只有一个基于上面的排序机制的子节点,例如我示例中右边的第一个移动。这很容易解决:我只是不更改树并适当更新拆分机制,将其应用于我已有的。
但是通过这样做,位于树的给定级别的所有值变得同样可能。因此第一个值对应于L(1/2),第二个值对应于RL(1/4),第三个值对应于RRL(1/8),最后一个值对应于RRR(1/8)。这些与我想要的概率非常不同!
所以我的问题是:如何为上面的采样程序构建一个有效的数据结构和遍历算法?