当前位置: 首页 > 知识库问答 >
问题:

选择概率与其值成比例且小于O(n)的数字的数据结构

庄浩言
2023-03-14

我有一组数字,[1,3,4,5,7]。我想从集合中选择一个概率与其值成正比的数字:

然而,我希望能够在不到O(n)的时间内更新和查询这个集合。是否有任何数据结构可以帮助我实现这一点?

最好是在Java,如果它已经存在

共有1个答案

巫马浩言
2023-03-14

您可以使用二叉索引树(也称为Fenwick树)进行分期查询和更新(包括删除/插入元素)。其思想是使用动态调整大小,这与在可变大小数组和哈希表中使用的获得摊销固定时间附加值的技巧相同。这还意味着您应该能够使用从动态数组中重建第二个数组的方法来获得O(logn)最坏情况的边界,但这会使代码明显变长。

首先,我们知道,给定arr的部分和列表,以及[0,sum(arr)]中的一个随机整数,我们可以在O(logn)时间内通过二进制搜索来实现这一点。具体来说,如果我们的随机整数是r,我们希望最右边部分和的索引小于或等于r

现在,我们将使用Fenwick树的这篇文章中的技术来维护和查询部分和。那篇帖子与你的略有不同:他们有一组固定的n键,它们的权重可以更新,无需新的插入或删除。

Fenwick树是一个数组,允许您在每次查询的O(logn)time中回答有关“基”数组部分和的查询,并且可以在O(n)time中构建。尤其是,你可以

  1. arr小于或等于r
  2. 对于任何整数c,将arr[i]设置为arr[i]c

都在O(log n)时间。

首先将n零添加到arr(它现在是半满的),然后构建它的芬威克树。我们可以将“删除”元素视为将其权重设置为0。插入一个元素是通过将arr中最右边的非零元素后面的零作为新元素的位置来完成的。移除的元素和新元素最终可能会导致我们的阵列填满:如果我们达到75%的容量,重建我们的阵列和Fenwick树,将阵列大小加倍(在右边用零填充)并删除所有零权重元素。如果我们达到25%的容量,将阵列缩小到一半大小,同时重建芬威克树。

您需要不断维护arr才能重建,因此所有更新都必须在arr和芬威克树上完成。您还需要一个从数组索引到密钥的哈希映射,以便进行随机选择。

好的一面是,您根本不需要修改Fenwick树内部:给定Java中支持初始化、数组更新和二进制搜索的Fenwick树实现,您可以将其视为黑盒。如果您想要最坏情况下的时间保证,这就不再是真的了:然后,您需要一点一点地复制Fenwick树的内部状态,这有一些复杂性。

 类似资料:
  • 让我们假设我有一个这样的结构化数组: 我将这个结构称为“categories”,所以,我在这个数组中有六个类别。我的目标是根据一个类别随机挑选一个产品。 我想做一个基于速率的类别选择,据我所知,我必须计算这个类别在数组中代表多少百分比,例如: 这会给我类似的东西: 好的,现在我要做一个简单的算法,根据这些比率得到类别;我想我现在需要在范围之间选择一个随机数,并制作一些“切片”,例如: 如果随机数介

  • 如何实现以下函数都在O(log N)中的数据结构? 插入(x)-将整数添加到集合 成员(x)-检查集合是否包含整数x 删除(x)-从集合中删除整数x deleteLessThan(x)删除所有等于或小于k的数字 我唯一能想到的就是使用某种平衡的BST来获取插入、成员和删除的O(logn)。 deleteLessthan()函数看起来像这样:找到大于k的最小元素,删除它的左子树,然后重新平衡。但是,

  • 我正在构建一个游戏,我想在到之间选择一个随机数,我想让选择一个更高的数字的几率更低。 所以我问了这个问题,根据amit的回答,我写了这样一句话: 输出我在10000次跑步中选择每个数字的次数。 问题是,无论我选择的值是多少,我总是得到相同的输出。 我需要找到一种方法来修复这个算法,以便将影响拾取两个不同值之间的机会比率,而主要思想将保持不变:拾取更高的值将更难。

  • 我需要设计一个数据结构的想法,它可以在 O(logn)时间内插入、删除和获取平均值(a,b)。getmean(a,b)是[a,b]中所有数字x的算术平均值 我的想法- 一般来说,如果我们将数据存储在像AVL树这样的平衡搜索树中,插入和删除操作可以在O(logn)时间内完成。但是为了在O(logn)时间内求解getmean(a,b),我们需要存储一些额外的信息。为了计算平均值,我们可以做以下操作:

  • 问题内容: 如何根据分配给每一行的概率机会从数据库中选择随机行。 例子: 如何根据必须选择的可能性来选择随机的品牌名称及其值。 和可以结合使用吗?如果是这样,最好的方法是什么? 问题答案: 您可以通过使用然后再使用累积和来执行此操作。假设它们的总和为100%: 笔记: 在子查询中被调用一次以初始化变量。多次调用是不可取的。 随机数极有可能恰好位于两个值之间的边界上。的任意选择1。 通过在时停止子查

  • 我希望使用本文提供的答案从列表中随机选择独特的项目。 按照所描述的方法,在我的循环的每次迭代中,我都会生成一个概率值,它是当前项目从列表中被选中的概率百分比。 我需要知道的是,我如何使用这个百分比值来选择项目(或不选择)。 这是我拥有的代码,是