在非常大的数组中找到 N 个唯一随机数的最佳算法

Best algorithm to find N unique random numbers in VERY large array

我有一个数组,例如,包含 1000000000000 个元素(整数)。例如,从该数组中仅选择 3 个随机且独特的元素的最佳方法是什么?元素在整个数组中必须是唯一的,而不是在 N 个(在我的示例中为 3 个)元素的列表中。

我读过关于 Reservoir sampling 的内容,但它只提供了选择随机数的方法,它可以是非唯一的。

counts = [0] * (MAXINT-MININT+1)
for value in Elements:
  counts[value] += 1
uniques = [c for c in counts where c==1]
result = random.pick_3_from(uniques)

如果命中非唯一值的几率很低,您最好的选择是从数组中 select 3 个随机数,然后对照整个数组检查每个数以确保它是唯一的 - 如果不行,另选一个随机样本代替,重复测试。

如果命中非唯一值的几率很高,这会增加您需要扫描数组以寻找唯一性的次数,并使简单的解决方案成为非最佳解决方案。在这种情况下,您需要将确保唯一编号的任务与制作随机 selection.

的任务分开

对数组进行排序是查找重复项的最简单方法。大多数排序算法都是 O(n log n),但由于您的键是整数 Radix sort 可能会更快。

另一种可能性是使用散列 table 来查找重复项,但这需要大量 space。您可以使用较小的散列 table 或 Bloom filter 来识别潜在的重复项,然后使用另一种方法遍历较小的列表。

我假设您对数组值的哪一部分可能是唯一的有一个合理的认识。所以你会知道,例如,如果你选择了 1000 个随机数组值,那么一个是唯一的可能性很大。

第 1 步。选择 3 个随机哈希算法。它们可以都是相同的算法,只是您在第一步中为每个算法添加了不同的整数。

第二步,扫描阵列。以三种方式对每个整数进行哈希处理,对于每个哈希算法,跟踪您获得的 X 个最低哈希码(您可以为此使用优先级队列),并保留每个哈希值 table 的哈希值 table出现整数。

第 3 步。对于每个哈希算法,在该桶中查找唯一元素。如果它已经在另一个桶中被拾取,请找到另一个。 (应该是罕见的边界情况。)

这是你的一组三个随机独特元素。每个唯一的三元组被选中的几率应该是偶数。

(注意:出于多种目的,只使用一种哈希算法并从其列表中找到 3 个东西就可以了...)

该算法一次遍历数组就很有可能成功。更好的是它使用的中间数据结构相当小并且易于合并。因此,对于非常大的数据集,这可以跨机器并行化。