【问题标题】:Shuffling a huge range of numbers using minimal storage使用最少的存储空间对大量数字进行洗牌
【发布时间】:2011-09-02 23:09:03
【问题描述】:

我有一个非常大的范围/一组数字,(1..1236401668096),我基本上想“洗牌”,即随机遍历 而不重新访问相同的数字。我将运行一个 Web 服务,每次收到请求时,它都会增加一个计数器并从该范围中提取下一个“混洗”数字。该算法必须适应服务器离线,能够使用计数器的持久值重新开始遍历(类似于如何为伪随机数生成器播种,并在给定种子的情况下获得相同的伪随机数和您正在进行哪个迭代)。

我想知道这样的算法是否存在或是否可行。我见过Fisher-Yates Shuffle,但第一步是“写下从 1 到 N 的数字”,这将占用我整个范围的 TB 存储空间。为每个请求生成一个伪随机数可能会工作一段时间,但随着数据库/树变满,冲突将变得更加普遍,并且可能会降低性能(根据我的计算,在 10 亿次点击后发生冲突的可能性为 0.08%)。对于我的方案,是否有更理想的解决方案,或者这只是一个白日梦?

改组的原因是能够正确猜测序列中的下一个数字可能会导致我的应用程序中出现轻微的 DOS 漏洞,而且还因为表示层在更广泛的数字分布下看起来会更好(I' d 宁愿不详细了解应用程序的具体功能)。在这一点上,我正在考虑只使用 PRNG 并处理冲突或改组范围切片(从 (1..10000000).to_a.shuffle 开始,然后是 (10000001, 20000000).to_a.shuffle 等,因为每个范围的数字开始用完)。

任何数学家有更好的想法/建议吗?

【问题讨论】:

  • 一种选择是使用linear feedback shift register,尽管它们不是加密安全的。
  • 为什么不使用时间戳和伪随机数或散列的组合来降低冲突的可能性?

标签: ruby random set range shuffle


【解决方案1】:

使用/dev/random 位连接 PRNG 或 LFSR 序列

有几种算法可以生成任意大且已知周期的伪随机数。两个明显的候选者是 LCPRNG (LCG) 和 LFSR,但还有更多算法,例如 Mersenne Twister。

这些发生器的周期可以很容易地构建以满足您的要求,然后您就不会发生冲突。

您可以通过从/dev/random. 之类的接口添加 10、20 或 30 位加密散列熵来处理 PRNG 和 LFSR 的可预测行为,因为已知数字的确定性部分是唯一的,所以没有区别如果你曾经重复它的实际随机部分。

【讨论】:

  • 我喜欢这个声音!我将尝试创建一个 m 值为 1236401668096 的 LCG。我不太担心它是严格加密安全的,所以我可能会跳过 /dev/random 部分。如果没有其他好的答案出现,我会将其标记为已接受。
【解决方案2】:

分而治之?分解成可管理的块并将它们洗牌。您可以划分数字范围,例如通过它们的值模 n。该列表是建设性的,并且非常小,具体取决于 n。一组用完后,可以使用下一组。

例如,如果您选择 n 为 1000,您将创建 1000 个不同的组。选择一个介于 1 和 1000 之间的随机数(我们称之为 x)并将其值模 1000 等于 x 的数字打乱。一旦你用尽了这个范围,你可以在 1 到 1000 之间选择一个新的随机数(显然没有 x)来获得下一个要洗牌的子集。跟踪 1..1000 范围内的哪些数字已经被使用应该不是什么难事,因此您只需要对子集中的数字使用可重复的洗牌算法(例如,Fisher-Yates 的“索引” ”)。

【讨论】:

  • 是的,我考虑过这个(倒数第二段的结尾);你可能错过了,因为我的帖子太冗长了(我在 tl;dr 的事情上失败了)。很高兴这对其他人来说似乎也是一个有效的解决方案!
  • @Abe:我有点想念它,但我也建议了一种比顺序切片不太明显的分区方式。
【解决方案3】:

我想最好的选择是使用GUID/UUID。它们是为这类事情而设计的,应该不难找到适合您需求的现有实现。

虽然理论上可能发生碰撞,但它们极不可能发生。引用维基百科:

如果地球上每个人都拥有 6 亿个 UUID,那么出现重复的概率约为 50%

【讨论】:

  • UUID 肯定会防止冲突,但是当我必须将其截断回较小的地址空间时,我相信我会再次遇到冲突。不幸的是,我无法扩展我的地址空间以减少冲突的可能性。感谢您的想法!
猜你喜欢
  • 2013-01-15
  • 2015-10-09
  • 2020-02-12
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
相关资源
最近更新 更多