Algorithm 加权项的快速采样和更新(数据结构,如红黑树?)

Algorithm 加权项的快速采样和更新(数据结构,如红黑树?),algorithm,data-structures,statistics,Algorithm,Data Structures,Statistics,此任务的适当数据结构是什么 我有一组N项。N是大的。 每个项目都有与其关联的正权重值 我想尽快完成以下工作: 内环: 根据一件物品的重量取样 [过程…] 更新K个项目的权重,其中K实际上,您可以为此使用(修改的)RB树。此外,任何平衡树的修改(不一定是二进制的)都可以 诀窍是在每个节点中存储额外的信息——在您的例子中,它可以是根在节点上的子树的总权重,或者类似的东西 当你更新(即插入/删除)树时,你要遵循你最喜欢的树的算法。更改结构时,只需重新计算节点的和(这是一个O(1)操作,例如旋转和B树拆

此任务的适当数据结构是什么

我有一组N项。N是大的。 每个项目都有与其关联的正权重值

我想尽快完成以下工作:

内环:

根据一件物品的重量取样

[过程…]

更新K个项目的权重,其中K实际上,您可以为此使用(修改的)RB树。此外,任何平衡树的修改(不一定是二进制的)都可以

诀窍是在每个节点中存储额外的信息——在您的例子中,它可以是根在节点上的子树的总权重,或者类似的东西

当你更新(即插入/删除)树时,你要遵循你最喜欢的树的算法。更改结构时,只需重新计算节点的和(这是一个O(1)操作,例如旋转和B树拆分和连接)。更改项目的权重时,将更新节点祖先的总和

采样时,运行的是修改后的搜索版本。得到树中所有权重的和(即根的和),并生成一个小于此值的正随机数。然后,运行搜索算法,如果数字(搜索的分位数)小于左节点的和,则转到左节点。如果转到右节点,则从分位数中减去左和

这个描述有点混乱,但我希望它能有所帮助。

实际上,您可以使用(修改过的)RB树。此外,任何平衡树的修改(不一定是二进制的)都可以

诀窍是在每个节点中存储额外的信息——在您的例子中,它可以是根在节点上的子树的总权重,或者类似的东西

当你更新(即插入/删除)树时,你要遵循你最喜欢的树的算法。更改结构时,只需重新计算节点的和(这是一个O(1)操作,例如旋转和B树拆分和连接)。更改项目的权重时,将更新节点祖先的总和

采样时,运行的是修改后的搜索版本。得到树中所有权重的和(即根的和),并生成一个小于此值的正随机数。然后,运行搜索算法,如果数字(搜索的分位数)小于左节点的和,则转到左节点。如果转到右节点,则从分位数中减去左和


这个描述有点混乱,但我希望能有所帮助。

我喜欢jpalecek的答案。我想补充一点,获取随机数的最简单方法是(1)从均匀(0,1)分布生成u。(2) 将u乘以树中所有权重之和。

我喜欢jpalecek的答案。我想补充一点,获取随机数的最简单方法是(1)从均匀(0,1)分布生成u。(2) 将u乘以树中所有权重之和。

因为N是固定的,所以可以通过使用数组来解决这个问题,比如说v,其中v[i+1]=v[i]+weight[i],v[1]=weight[0],v[0]=0,并通过二进制搜索(即log(N))对均匀分布在0和权重之和之间的随机数的下限进行采样

K个项目的初始更新是O(KN),更周到的更新是O(N)


因为N是固定的,你可以通过使用一个数组来解决这个问题,比如说v,其中v[i+1]=v[i]+weight[i],v[1]=weight[0],v[0]=0,并通过二进制搜索(即log(N))对均匀分布在0和权重之和之间的随机数的下限进行采样

K个项目的初始更新是O(KN),更周到的更新是O(N)


破坏了自鸣得意圈的另一个采访问题:)

这是我在一些蒙特卡罗模拟中必须解决的问题。你可以在下面的链接中看到我当前的“二叉树”。我试着让它看起来很像STL。我的树有一个固定的容量,你可以用红黑树的方法来绕过它,我已经说过要尝试。它本质上是jpacelek描述的思想的实现

该方法在处理不精确浮点数时非常稳健,因为它几乎总是对相同数量级的数量进行求和和比较,因为它们在树中处于同一级别


对于一些蒙特卡罗模拟,这是我必须解决的问题。你可以在下面的链接中看到我当前的“二叉树”。我试着让它看起来很像STL。我的树有一个固定的容量,你可以用红黑树的方法来绕过它,我已经说过要尝试。它本质上是jpacelek描述的思想的实现

该方法在处理不精确浮点数时非常稳健,因为它几乎总是对相同数量级的数量进行求和和比较,因为它们在树中处于同一级别


如果使用不精确的表示法(如浮点),则更新权重之和可能会遇到困难。这不是一个大问题-最糟糕的情况是结果不准确。如果使用不精确的表示法,则更新权重之和可能会遇到困难,这不是什么大问题,最糟糕的情况是结果不准确。