繁体   English   中英

c ++具有频繁变化概率的离散分布采样

[英]c++ discrete distribution sampling with frequently changing probabilities

问题:我需要从由某些权重构成的离散分布中进行采样,例如{w1,w2,w3,..},从而得到概率分布{p1,p2,p3,...},其中pi = wi /(w1 + W2 + ...)。

一些wi的变化非常频繁,但只有非常低比例的所有wi。 但是,每次发生时,分布本身都必须重新规范化,因此我认为Alias方法不能有效地工作,因为每次都需要从头开始构建整个分布。

我目前正在考虑的方法是二叉树(堆方法),其中所有wi都保存在最低级别,然后是两个级别在更高级别中的总和,依此类推。 所有这些的总和将处于最高级别,这也是归一化常数。 因此,为了在wi中更改后更新树,需要进行log(n)更改,以及从分发中获取样本的相同数量。

题:

Q1。 你对如何更快地实现它有更好的想法吗? Q2。 最重要的部分:我正在寻找一个已经完成这项工作的图书馆。

解释:几年前我自己做了这个,通过在向量中构建堆结构,但从那时起我学到了很多东西,包括发现库(:))和容器如map ...现在我需要重写代码具有更高的功能,我想这次正确:

所以Q2.1有一个很好的方法可以使c ++地图不是通过索引进行排序和搜索,而是通过它的元素的累积和(这是我们的样本,对吧?)。 (这是我目前的理论,我想怎么做,但它不一定要这样......)

Q2.2也许还有一些更好的方法可以做到这一点? 我会相信这个问题是如此频繁,我很惊讶我找不到某种能为我做这件事的图书馆......

非常感谢,如果有其他形式的问题,我很抱歉,请指导我,但我花了很长时间看...

-z

编辑:我可能需要删除或添加元素,但我认为我可以避免它,如果这会产生巨大的差异,因此只留下改变权重的值。

Edit2:权重一般是实数,我不得不考虑是否可以使它们成为整数...

我实际上会使用一组哈希字符串(不记得它的C ++容器,你可能需要实现自己的)。 为每个i放置wi元素,值为“w1_1”,“w1_2”,......全部通过“w1_ [w1]”(即w1元素以“w1_”开头)。

需要采样时,使用均匀分布随机选取一个元素。 如果您选择了w5_ *,则说您选择了元素5.由于哈希中的元素数量,这将为您提供所需的分布。

现在,当wi从A变为B时,只需将BA元素添加到散列(如果B> A),或删除wi的最后AB元素(如果A> B)。

在这种情况下,添加新元素和删除旧元素是微不足道的。

显然问题是“随机挑选一个元素”。 如果你的哈希是一个封闭的哈希,你随机选择一个数组单元格,如果它是空的 - 只需再次随机选择一个。 如果你的哈希值比权重的总和大3或4倍,那么你的复杂性将非常好:O(1)用于检索随机样本,O(| AB |)用于修改权重。

另一种选择,因为只有一小部分重量发生变化,就是将重量分成两部分 - 固定部分和变化部分。 然后,您只需要担心更改部件的更改,以及更改部件的总重量与未更改部件的总重量之间的差异。 然后对于固定部分,您的哈希变为一个简单的数字数组:1出现w1次,2出现w2次等等,并且选择随机固定元素只是选择一个随机数。

更改值时更新标准化因子非常简单。 这可能暗示了一种算法。

w_sum = w_sum_old - w_i_old + w_i_new;

如果将p_i作为计算属性p_i = w_i / w_sum,则应避免重新计算整个p_i数组,但需要在每次需要时计算p_i。 但是,您可以在不重新计算总和的情况下更新许多统计属性

expected_something = (something_1 * w_1 + something_2 * w_2 + ...) / w_sum;

通过一些代数,您可以通过减去旧权重的贡献来更新expected_something,并使用新权重添加贡献,根据需要乘以和除以标准化因子。

如果您在采样期间跟踪哪些结果是样本的一部分,则可以传播概率如何更新为生成的样本。 这是否可以让您更新而不是重新计算与样本相关的值? 我认为位图可以提供一种有效的方法来存储用于构建样本的结果的索引。

将概率与总和一起存储的一种方法是从所有概率开始。 在接下来的N / 2个位置,您可以存储货币对的总和。 在那之后,总和所在的N / 4总和可以显然在O(1)时间内计算。 这种数据结构有点堆,但是颠倒了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM