【发布时间】: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