明确说明:
想象一下,您得到了一个对象列表。列表大小可以是任意的,但假定它很大(例如10,000,000个项目)。您需要以随机顺序打印出列表中的项目,并且需要尽快完成。但是,您不应:
这可能吗?
补充: 更多说明。
添加2 :好,让我们这样说:您有一个1TB的HDD,其中填充了数据项,每个数据项大512字节(单个扇区)。您想在将所有项目混排的同时将所有这些数据复制到另一个1TB HDD。您想要尽快执行此操作(单次传递数据等)。您有512MB的可用内存,不要指望交换。(这是一个理论上的场景,在实践中我没有这样的东西。我只是想找到理想的算法。)
这是一个非常简单的证明,没有PRNG方案可以工作:
PRNG的想法分为两个阶段:第一,选择PRNG及其初始状态。第二,使用PRNG随机输出。好吧,有 N! 可能的排列,因此您至少需要 N! 进入阶段2的可能的不同开始状态。这意味着在阶段2的开始时,您必须至少具有 _log 2 N!_状态位,这是不允许的。
但是,这并不排除算法从中接收来自环境的新随机位的方案。例如,可能有一个PRNG会 延迟 读取其初始状态,但可以保证不会重复。我们可以证明没有吗?
假设我们确实有一个完美的改组算法。想象我们开始运行它,当它完成一半时,我们使计算机进入睡眠状态。现在,程序的完整状态已保存在某个位置。设 S 为程序可能在此中间标记处的所有可能状态的集合。
由于该算法是正确的并且保证可以终止,因此存在一个函数 f ,在给定已保存的程序状态加上足够长的位字符串的情况下,该函数 f 会产生有效的磁盘读取和写入序列,从而完成随机播放。计算机本身实现此功能。但是将其视为数学函数:
f : (S×位)→读写顺序
然后,琐碎地存在一个函数 g , 仅 在给定的已保存程序状态的情况下,该函数会生成一组尚待读取和写入的磁盘位置。(只需将一些任意的字符串传递给 f ,然后查看结果即可。)
g : S → 设置读写位置
证明的剩余部分是要显示 g 的域至少包含 N C N / 2个_不同的集合,而与算法的选择无关。如果是这样,则必须至少有 _S个 元素,因此程序的状态必须在中途标记处至少包含 _log 2 N C N / 2_位,这违反了要求。
我不知道如何证明最后一位,不过,因为 无论是 在设定的-地点阅读 或 在设定的- 位置与写入光可低熵,这取决于算法。我怀疑信息理论中有一些显而易见的原理可以解决这个难题。标记此社区Wiki,以希望有人提供它。