Algorithm 实现随机删除和插入的数据结构,其中元素在[a,b]中加权

Algorithm 实现随机删除和插入的数据结构,其中元素在[a,b]中加权,algorithm,data-structures,randomized-algorithm,Algorithm,Data Structures,Randomized Algorithm,我想设计一个数据结构和算法,这样,给定一个元素数组,其中每个元素根据[a,b]具有权重,我就可以实现恒定时间的插入和删除。删除是随机执行的,其中删除元素的概率与其权重成正比 我不相信有一种确定性算法可以在恒定时间内实现这两种操作,但我认为应该有一些随机算法可以实现这一点?我不知道O1最坏情况下的时间是否不可能;我看不出有什么特别的原因。但是,有一个简单的数据结构来实现O1预期时间是绝对可能的 其想法是存储一对或两对,其中每个项目与其重量配对;插入是通过追加O1摊销时间来完成的,可以通过索引将某个

我想设计一个数据结构和算法,这样,给定一个元素数组,其中每个元素根据[a,b]具有权重,我就可以实现恒定时间的插入和删除。删除是随机执行的,其中删除元素的概率与其权重成正比


我不相信有一种确定性算法可以在恒定时间内实现这两种操作,但我认为应该有一些随机算法可以实现这一点?

我不知道O1最坏情况下的时间是否不可能;我看不出有什么特别的原因。但是,有一个简单的数据结构来实现O1预期时间是绝对可能的

其想法是存储一对或两对,其中每个项目与其重量配对;插入是通过追加O1摊销时间来完成的,可以通过索引将某个元素与最后一个元素交换来删除,以便在O1时间内将其从数组末尾删除。要从加权分布中抽样一个随机元素,请选择一个随机索引,并在半开区间内生成一个随机数[0,2;如果它小于元素的权重,则选择该索引处的元素,否则重复此过程,直到选择一个元素。其思想是,每个索引被选择的可能性相等,保留而不是拒绝的概率与其权重成正比

这是a,意味着它预计在有限的时间内完成,但概率很低,可能需要任意长的时间才能完成。当每个权重正好为1时,元素采样所需的迭代次数将最高,在这种情况下,它遵循参数p=1/2的a,因此其预期值为2,这是一个独立的常数数据结构中元素数量的依赖关系


一般来说,如果实数0
| value | weight |
| v1    | 1.0    |
| v2    | 1.5    |
| v3    | 1.5    |
| v4    | 2.0    |
| v5    | 1.0    |
| total | 7.0    |
总重量为7.0。通过将其存储在一些内存中并在每次插入/移除时增加/减少,可以很容易地在O1中进行维护

每个元素的概率就是它的权重除以总权重

| value | proba |
| v1    | 1.0/7 | 0.1428...
| v2    | 1.5/7 | 0.2142...
| v3    | 1.5/7 | 0.2142...
| v4    | 2.0/7 | 0.2857...
| v5    | 1.0/7 | 0.1428...
使用@kaya3算法,如果我们画一个随机指数,那么每个值的概率是1/1/5

被拒绝的概率v1为50%,v2为25%,v4为0%。因此,在第一轮中,被选择的概率为:

| value | proba  |
| v1    |  2/20  | 0.10
| v2    |  3/20  | 0.15
| v3    |  3/20  | 0.15
| v4    |  4/20  | 0.20
| v5    |  2/20  | 0.10
| total | 14/20  | (70%)
第二轮的概率为30%,每个指标的概率为6/20/5=3/50

| value | proba 2 rounds |
| v1    |  2/20 +  6/200 | 0.130
| v2    |  3/20 +  9/200 | 0.195
| v3    |  3/20 +  9/200 | 0.195
| v4    |  4/20 + 12/200 | 0.260
| v5    |  2/20 +  6/200 | 0.130
| total | 14/20 + 42/200 | (91%)
第三轮的概率为9%,即每个指数为9/500

| value | proba 3 rounds            |
| v1    |  2/20 +  6/200 +  18/2000 | 0.1390
| v2    |  3/20 +  9/200 +  27/2000 | 0.2085
| v3    |  3/20 +  9/200 +  27/2000 | 0.2085
| v4    |  4/20 + 12/200 +  36/2000 | 0.2780
| v5    |  2/20 +  6/200 +  18/2000 | 0.1390
| total | 14/20 + 42/200 + 126/2000 | (97,3%)
所以我们看到序列正收敛到正确的概率。分子是权重的倍数,所以很明显每个元素的相对权重都得到了尊重。

这是一个答案的草图

当权重只有1时,我们可以保持输入的随机排列。 每次插入一个元素时,将其放在数组的末尾,然后在数组中选择一个随机位置i,并将最后一个元素与位置i处的元素交换。 如果随机位置最终被证明是最后一个位置,那么这很可能是不可行的。 删除时,只删除最后一个元素

假设我们可以使用O1最坏情况下的动态数组或摊销插入和删除,这将在O1中执行插入和删除操作

对于重量1和2,可以使用类似的结构。 也许权重2的每个元素应该放置两次而不是一次。 可能当删除权重为2的元素时,其其他副本也应删除。 因此,我们实际上应该存储索引而不是元素,以及另一个数组locations,它存储并跟踪每个元素的两个索引。交换应该使这个locations数组保持最新


删除任意元素可以在O1中完成,类似于插入:与最后一个元素交换,删除最后一个元素。

这与您之前的问题有什么显著不同?前面的问题提到了这些权重作为一个例子。那么您是说询问特定案例构成了一个不同的问题?@pjs Uh no?我刚刚在前面的问题中编了一个例子,甚至没有意识到我编了一个,所以它与我要问的类似。这是一个完全不同的问题,看看权重约束是否有什么重要意义。如果它让你更快乐,我会将前面问题的例子改为另外两个数字。算法的性能会更好epends假设存在边界;它之所以有效,是因为权重不能任意小或任意大。在一般情况下,这不是一个合适的解决方案,在一般情况下实现它也不容易,因为拒绝采样需要在区间内生成一个随机数[0,b意味着知道b是什么,即知道b的最大可能性
重量轻。支持高效的max查询和高效的索引删除的数据结构将非常复杂。@pjs它并不是询问具体的情况;在这个问题中,对输入有更多的保证,应该利用这些保证来实现更高效的算法。这与未排序列表中的搜索不是同一个问题线性搜索和排序列表中的搜索二进制搜索是同一个问题;在输入上添加一个约束会大大改变它。我不明白为什么我们会在半开区间内生成一个随机数$[0,2$。这些界限从何而来?@user5965026请参见下面的示例,如果不确定,请逐步重做。最糟糕的情况是,如果所有权重都等于a-如果任何权重都较大,则终止的可能性更大。如果每个迭代都有a/b终止的机会,则需要预期的b/a迭代onte carlo模拟似乎也独立于a和b。对于a,b,n的任何选择,我基本上总是得到大约2的迭代次数。如果你在区间[a,b]中均匀地选择权重那么这听起来是对的;如果你的大多数权重都在下限,那么你会看到更高的预期迭代次数。为了确信边界,你必须用[a,b]中的符号值而不是数值来重做一个例子。在[a,b]中选择权重w的几率是w/b。在每一轮中,你得到p=proba\u,这轮*1/尺寸*w/b来选择一些权重元素w…kaya3答案解释了它的工作原理,上面的公式应该回答它的工作原理,所以我认为你得到了所有元素。你可以取[2,4],它将与[1,2]相同.重要的是较低和较高重量之间的比率。因此,如果你有重量[0.5,2],你将平均获得更多轮。作为练习,你应该获得99个概率为0.01%的值,以及一个概率为99.01%的值,并检查获得第二轮的概率…我现在正在更详细地研究这个问题。这个算法有名字吗?我想了解一些关于某人如何提出这个算法的背景。是的,拉斯维加斯,单击链接在kaya3的答案中,一切都在那里。权重可以是浮点值。我认为只有当权重被限制为1和2时,这个算法才有效?尽管我对这种解释很感兴趣,但仔细想想。@user5965026这个答案解决了你下面的具体问题:权重的构造有什么特殊之处吗对[1,2]?这就是小整数权重的特殊之处:我们可以使用它们作为置换中的出现次数。啊,是的。我对你的答案投了赞成票,因为我最初不清楚权重是否可以是浮点。你可以更详细地概述一下你的算法吗?具体来说,你似乎建议我们应该有2个数组,但你是说这两个数组都应该存储索引而不是元素吗?我设想的可能是一个数组和一个哈希表。哈希表的键是元素,值是索引。数组包含所有元素,每个元素有两个项,权重为2,每个元素有一个项权重为1….续..然后从元素数组中随机取样。假设取样的是arr[i],然后您将获取此元素并将其从哈希表中删除,但在删除之前,您会找到此元素的第二个索引(如果有)。然后您需要删除此元素及其重复的对应项。您可以将其与数组中的最后2个位置交换。