C++ 加权随机数V2(动态情况)

C++ 加权随机数V2(动态情况),c++,c,random,sampling,C++,C,Random,Sampling,此问题是链接下方问题的延伸 我的问题是采样加权随机数,附加条件是每个元素的权重经常动态变化 编辑 假设有N个元素具有不同的权重 对于静态权重,Walker的alias方法需要O(N)时间来设置别名,但采样成本为O(1),因此它是实现我的目标的最佳方法之一 二元搜索法也需要O(N)来生成累积数组,采样代价为log(N) 然而在我的例子中,由于权重经常改变,修改权重的时间复杂性也很重要 因此,我想知道,对于修改数据结构和采样,现有库或算法的时间复杂度都小于O(N) 当我阅读评论时,我意识到我需要附

此问题是链接下方问题的延伸

我的问题是采样加权随机数,附加条件是每个元素的权重经常动态变化

编辑 假设有N个元素具有不同的权重

对于静态权重,Walker的alias方法需要O(N)时间来设置别名,但采样成本为O(1),因此它是实现我的目标的最佳方法之一

二元搜索法也需要O(N)来生成累积数组,采样代价为log(N)

然而在我的例子中,由于权重经常改变,修改权重的时间复杂性也很重要

因此,我想知道,对于修改数据结构和采样,现有库或算法的时间复杂度都小于O(N)

当我阅读评论时,我意识到我需要附加条件。在每个修改阶段,只修改少数(主要是两个)权重,而且这些修改不会改变权重的总和(标准化条件)


如果有解决方案,我还想知道当权重也是实数时是否可以使用它。

我面临同样的问题。我将描述我目前解决该问题的计划,但如果有任何其他建议和/或实施指南,我将不胜感激


我目前的计划是调整动态订单统计的算法,如Cormen/Leiserson/Rivest的“算法简介”第14.1节所述。将元素放入一个平衡的二叉树中,例如红黑树,并将权重作为键。您可以扩充树,以便每个节点在其子树中存储权重之和。然后根将权重的总和存储在整个树中,例如
S
。子树和可以在树操作期间更新,更新方式与动态顺序统计的子树大小相同。要进行加权采样,您需要在
[0..S]
中统一采样一个数字,比如说
x
;然后在树下搜索节点
N
,这样在顺序遍历中
N
之前的节点的权重之和就是
,我面临同样的问题。我将描述我目前解决该问题的计划,但如果有任何其他建议和/或实施指南,我将不胜感激


我目前的计划是调整动态订单统计的算法,如Cormen/Leiserson/Rivest的“算法简介”第14.1节所述。将元素放入一个平衡的二叉树中,例如红黑树,并将权重作为键。您可以扩充树,以便每个节点在其子树中存储权重之和。然后根将权重的总和存储在整个树中,例如
S
。子树和可以在树操作期间更新,更新方式与动态顺序统计的子树大小相同。要进行加权采样,您需要在
[0..S]
中统一采样一个数字,比如说
x
;然后在树下搜索节点
N
,这样在遍历顺序中
N
之前的节点的权重之和是
N是链接中的元素数,N=3{1,2,3}好的,我明白了。总体复杂性可能取决于您需要修改权重的频率;你是说每次迭代都需要这样做吗?是的,在我的问题中,权重是由之前采样的元素改变的。所以我需要在每次迭代中修改权重。你是在每次迭代中修改所有的权重(在这种情况下,你可能运气不佳),还是只修改几个?如果只修改O(1)大部分只有两个权重呢??另外,如果修改没有改变总权重,那么不需要规范化?N是链接中的元素数,N=3{1,2,3}好的,我明白了。总体复杂性可能取决于您需要修改权重的频率;你是说每次迭代都需要这样做吗?是的,在我的问题中,权重是由之前采样的元素改变的。所以我需要在每次迭代中修改权重。你是在每次迭代中修改所有的权重(在这种情况下,你可能运气不佳),还是只修改几个?如果只修改O(1)大部分只有两个权重呢??另外,如果修改没有改变总重量,那么不需要正常化?