提问人:Daniel 提问时间:8/22/2023 更新时间:9/21/2023 访问量:50
在 O(1) 时空复杂度中选择加权任务
Choosing a weighted task in O(1) space-time complexity
问:
假设我有一个任务列表 L。每个任务都由一个整数权重表示,该权重表示任务的重要性。
任务的重要性不会影响其顺序,但会影响其被选中的机会。例如:如果我有 2 个任务 A 和 B,权重分别为 3 和 1,则 A 将有 75% 的机会被选中,而 B 有 25% 的机会被选中。
我怎样才能有一个恒定的时间/空间算法,从任务列表中选择一个随机任务,并考虑其权重?
我目前的解决方案是在 0 和 L 中所有元素的总和之间选择一个随机数。然后我像这样遍历 L:
int random = RandomInInterval(0, sumOfL);
foreach(Task T in L){
random -= T;
if(random <= 0) return T;
}
这在空间上是恒定的,但在时间上是线性的。有没有办法做一个时间常数的解决方案?
一旦我设置了 L,它就不会改变,所以计算权重之和的复杂性可以忽略不计,因为我只会计算一次。另一方面,我将一直选择任务。
答:
1赞
Matt Timmermans
8/22/2023
#1
恒定时间将需要一个查找表。您可以使用它来优化您已有的程序。
- 将范围从 0 划分为大小相等的区域,这些区域足够小,以便每个区域与最多 2 个任务的范围重叠。使区域大小小于最小任务范围将确保这一点。
sumOfL
- 创建一个区域数组,为每个区域记录它对应的单个任务,或者两个任务以及它们之间的分界线。
现在,您可以在恒定时间内选择一个区域:
- 生成一个随机数
[0, sumOfL)
- 除以数组中的区域大小和索引以查找区域
- 如有必要,根据区域的分界线测试随机数,以确定要选择的两个任务中的哪一个。
评论
0赞
Daniel
8/23/2023
似乎不可能有 O(1) 空间复杂度......
0赞
Chris
9/21/2023
#2
我为此编写了一个库:https://github.com/cdanek/KaimiraWeightedList
如果你想自己卷,你需要花一点。首先阅读别名方法并查看 Keith Schwartz 的解释(这真的很好)。
不幸的是,您将无法获得 O(1) 空间复杂度。O(N),是的,O(1),不,O(1)处理用例(gets)的复杂性是可能的。
上一个:如何对比率指标正确运行回归调整?
下一个:鞅和顺序相关 [已关闭]
评论