一尘不染

用于在现场并使用O(1)内存打印混洗的列表的算法

algorithm

明确说明:

想象一下,您得到了一个对象列表。列表大小可以是任意的,但假定它很大(例如10,000,000个项目)。您需要以随机顺序打印出列表中的项目,并且需要尽快完成。但是,您不应:

  • 复制原始列表,因为它很大,复制会浪费很多内存(可能会超出可用RAM的限制);
  • 修改原始列表,因为它是以某种方式排序的,以后的其他部分取决于它的排序方式。
  • 创建索引列表,因为该列表又很大,并且复制占用了太多时间和内存。(澄清:这表示其他任何列表,其元素数与原始列表相同)。

这可能吗?

补充: 更多说明。

  1. 我希望列表以真正随机的方式进行混洗,所有排列的可能性均相同(当然,假设我们有一个合适的Rand()函数开始)。
  2. 我提出的一个指针列表,一个索引列表或任何其他元素列表数量与原始列表相同的建议,被原始问题明确认为是无效的。您可以根据需要创建其他列表,但是它们应比原始列表小几个数量级。
  3. 原始列表就像一个数组,您可以通过O(1)中的索引从其中检索任何项目。(因此,没有双向链接的列表内容,您必须在列表中进行迭代才能找到所需的项目。)

添加2
:好,让我们这样说:您有一个1TB的HDD,其中填充了数据项,每个数据项大512字节(单个扇区)。您想在将所有项目混排的同时将所有这些数据复制到另一个1TB
HDD。您想要尽快执行此操作(单次传递数据等)。您有512MB的可用内存,不要指望交换。(这是一个理论上的场景,在实践中我没有这样的东西。我只是想找到理想的算法。)


阅读 208

收藏
2020-07-28

共1个答案

一尘不染

这是一个非常简单的证明,没有PRNG方案可以工作:

PRNG的想法分为两个阶段:第一,选择PRNG及其初始状态。第二,使用PRNG随机输出。好吧,有 N! 可能的排列,因此您至少需要 N!
进入阶段2的可能的不同开始状态。这意味着在阶段2的开始时,您必须至少具有 _log 2 N!_状态位,这是不允许的。

但是,这并不排除算法从中接收来自环境的新随机位的方案。例如,可能有一个PRNG会 延迟 读取其初始状态,但可以保证不会重复。我们可以证明没有吗?

假设我们确实有一个完美的改组算法。想象我们开始运行它,当它完成一半时,我们使计算机进入睡眠状态。现在,程序的完整状态已保存在某个位置。设 S
为程序可能在此中间标记处的所有可能状态的集合。

由于该算法是正确的并且保证可以终止,因此存在一个函数 f ,在给定已保存的程序状态加上足够长的位字符串的情况下,该函数 f
会产生有效的磁盘读取和写入序列,从而完成随机播放。计算机本身实现此功能。但是将其视为数学函数:

f(S×位)→读写顺序

然后,琐碎地存在一个函数 g 在给定的已保存程序状态的情况下,该函数会生成一组尚待读取和写入的磁盘位置。(只需将一些任意的字符串传递给
f ,然后查看结果即可。)

gS设置读写位置

证明的剩余部分是要显示 g 的域至少包含 N C N / 2个_不同的集合,而与算法的选择无关。如果是这样,则必须至少有 _S个
元素,因此程序的状态必须在中途标记处至少包含 _log 2 N C N / 2_位,这违反了要求。

我不知道如何证明最后一位,不过,因为 无论是 在设定的-地点阅读 在设定的-
位置与写入光可低熵,这取决于算法。我怀疑信息理论中有一些显而易见的原理可以解决这个难题。标记此社区Wiki,以希望有人提供它。

2020-07-28