在阅读 这个问题 我开始想:是否有可能有一种洗牌的算法,这并不修改或复制的原件列表吗?

要清楚:

想象一下,给你一个名单的对象。本列表的大小可以是任意的,但假设这是很大的(说,10,000,000的项目)。你需要打印出的项目清单中随机了,你需要做的是尽可能快。但是,你不应该:

  • 复制的原始清单,因为这是非常大和复制的会浪费大量的存储器(可能击中的限制提供RAM);
  • 修改原始清单,因为它是以一些方式及其他一些部分后来取决于它正在进行排序。
  • 建立一个索引清单,因为,再有,该名单是非常大和复制需要所有太多的时间和存储器中。(说明:这意味着任何其他清单,其中有数量相同的要素作为原始名单)。

这可能吗?

添加: 更多的澄清。

  1. 我想要的列表中被打乱,在真正随机的方式排列组合可能性均等(当然,假设我们有一个适当的Rand()function开始与)。
  2. 建议,我让一个列表中的指针,或列出的指数或任何其他名单,将具有相同的元素数量原始清单,被明确视为效率低下,通过原来的问题。你可以创造额外的清单,如果你想要的,但他们应该严肃的数量级上小于原来的名单。
  3. 原来的名单是像一阵列,并且可以检索的任何项目从它通过其指数在O(1)。(所以没有双链表的东西,你必须循环访问的名单得到你想要的项目。)

加入2:好吧,让我们把这种方式:你有1TB硬盘填充数据项目,每个项目512字节大的(单个部门).你想要复制所有这种数据的另一个1TB硬盘而洗牌的所有项目。你想这样做,尽可能快的(单个传过来的数据,等等)。你有512mb RAM可用,而不计在交换。(这是一个理论上的方案中,我没有任何东西,像这样的做法。我只是希望找到完美的算法。项。)

有帮助吗?

解决方案

这是一个非常简单的证据,没有养恤金条例》的方案可能的工作:

《养恤金条例》的想法有两个阶段:第一,选择一个《养恤金条例》和其初始状态;第二,使用《养恤金条例》洗牌的输出。嗯,有 N! 可能的置换,因此至少需要 N! 不同的可能开始国家,进入第2阶段。这意味着,在开始第2阶段必须有至少 日志2 N! 位的国家,这是不允许的。

然而,这并不排除计划,其中的算法接收新的随机从位的环境。可能有,也就是说,一个养恤金条例》,读取它的初始状态 懒洋洋地 但是保证不重复。我们可以证明没有?

假设我们有一个完美的洗牌的算法。想象一下我们开始运行,以及当它的一半做,我们就把计算机的睡眠。现在全国的程序已被储存的地方。让 S 被设定的所有可能的国家的程序可能在这一半标志。

因为算法是正确的,并保证终止,有一个功能 f 其中,给予保存的程序状态以及任何足够长串位,产生了一个有效序的磁盘读写完成的洗牌。计算机本身实现这一功能。但考虑它作为一个数学功能:

f : (S×位)→序的读和写

然后,平凡,存在着一个功能 其中,由 保存的程序的状态,产生一套盘点尚未阅读和书写。(简单地通过一些任意字符串位 f, 然后看看结果。)

: S设定的位置阅读和写

剩下的位的证明是要表明,该领域的 至少含有 NCN/2 套不同而无论所选择的算法。如果这是真的,必须至少有许多元素 S, 等等的状态的程序必须至少含有 日志2 NCN/2 位在半路标记,违反了要求。

我不知道如何证明最后一点,不过,由于 要么 设定的位置读 设定的位置写可以低熵,根据不同的算法。我怀疑有一些明显的原则信息的理论,可以切结。标志这个社会wiki希望会有人来源。

其他提示

嗯,这取决于一个位于什么样的随机性的,你除了洗牌,即都应该shufflings被作为可能的、或可能的分布是偏斜的。

有数学的方式产生的"随机的-看"排列的N整数,因此,如果P是这样的一个置换从0..N-1至0..N-1,你就可以迭代x从0到N-1和输出清单项目L(P(x)),而不是L(x)以及你获得一个洗牌。这样的排列组合可以获得例如使用模块化的算术.例如,如果N总理,P(x)=(x*k)国防部N是一个排列的任何0 < k < N(但地图0 0)。类似地对总理N,例如P(x)=(x^3)国防部N应该是一个置换(但地图0 0和1来文1)。这个解决方案可以很容易地扩大到非国总理N由选择的少总理上述N(称它M),重排达米,并放弃置换指数上N(类似地下)。

应当指出,模块化指数的基础是很多加密算法(例如RSA,迪菲-赫尔曼)和被认为是一个强烈的伪随机的操作,由专家在现场。

另一种简单的方法(不需要总理的数字)是第一个扩大的领域如此,而不是你考虑的M M是少电的上述两个N。所以如若N=12,你设M=16.然后你用双射位的运作,例如

P(x) = ((x ^ 0xf) ^ (x << 2) + 3) & 0xf

然后当你输出你的名单,你迭代x从0到M-1和输出L(P(x))仅有,如果P(x)是实际上 < N.

"真实的、不偏不倚的随机"的解决方案可以构成通过固定保密性强的框密(例如AES)和随机的关键(k)和再循环的顺序

AES(k, 0), AES(k, 1), ...

和输出相应的项目列森林论坛AES(k,i) < N.这可以通过在不断空间的(内部存储器所需的密码)并没有区别随机排列(由于加密性加密的)但是显然非常缓慢。在这种情况下的AES,你会需要迭代,直至i=2^128.

你不允许进行复制、修改,或跟踪其元素,你已经访问了?我要说这是不可能的。除非我误会你的第三个标准。

我是否意味着你不能说,使一系列的10,000,000的相应布尔、设置为真正的时候你已经印刷相应的元素。而你不允许列出的10,000,000指数、洗牌的名单,并且打印出来的要素。

这些项目10,000,000的只是参考(或指针)为实际的项目,所以您的名单将不大。只-40MB在32位架构,为所有参考文献+尺寸的内部的变量的清单。在情况下,当项目小于参考大小,你只是复制整个清单。

这是不可能做到这一点的 真的 随机数发生器,因为你无论有:

  • 记住这的号码已经选择和跳过他们,(其中要求O(n)清单的布尔和日益严重的运行时间为你跳过更多和更多的号码);或
  • 减少之后,每个选择(这需要修改原始名单或一个单独的O(n)列表,以修改)。

没有这些可能性在你的问题那我会说"不,你不能这样做"。

我倾向于去在这种情况下是一位掩使用价值但不跳,因为正如所述,运行时间变得更糟,因为所用值的累积。

一位掩将基本上比原来的名单39Gb(10亿位仅为约1.2米),许多数量级不如你要求,即使它仍然是O(n)。

为了得到周围的运行时间问题,只会产生一个随机数量的每一个时间,如果有关"使用"点是已经设置、扫描前通过位掩模,直到找到一个的 设置。

这意味着你不会被挂在绝望的随机数发生器来给你一个号码没有被使用。的运行时间将永远只能获得那么糟糕,因为时间所采取的扫描1.2米的数据。

当然这意味着特定数目的选择任何时候被歪曲的基础上的数字已经选择,但是,由于这些数字是随机的,无论如何,歪曲是随机的(以及如果数字 是不是 真正随机的开始,然后倾斜不物质)。

你甚至可以替代的搜索方向(扫描向上或向下)如果你想要一点更多的品种。

底线:我不相信你所要求的是可行的,但是请记住我错了之前我的妻子将证明,迅速和频繁:-)但是,如同所有的事情,没有通常的方式来绕过这些问题。

这听起来是不可能的。

但是10,000,000的64位指的是只有约76MB.

线性反馈移登记册可以做很多你想要什么--生成列表的人数达到某些限制,但在一个(理由)。该模式产生在统计上是类似于什么是你期望从尝试,随机性, 它甚至没有接近过加密的安全。该Berlekamp-Massey算法可以允许你来进行反向工程相当于一个扰根据一个产出的顺序。

鉴于你要求的列表,约10,000,000的项目,你想要一个24位的最大长扰,并简单地放弃输出更大的尺寸您的名单。

为什么它的价值,j=一般是相当快的速度相比,典型线性同余《养恤金条例》的相同的期间。在硬件、扰是 非常 简单,组成一个N位的注册,并米2输入XOR的(M是抽头数--有时候只有一对夫妇,且很少超过一半打左右)。

如果有足够的空间,你可以存储节点的指针在一系列创建一位图,并得到随机int这一点上到下一个选项。如果已经选择了(你的商店在你的位),然后得到最接近的一个(或左右,你可以随机这一),直到没有项目留。

如果没有足够的空间,然后你可以做同样,不存储节点的指针,但时间将遭受(这就是时间-空间的权衡互).

你可以创建一个伪随机,'安全的'排列,使用一组密码-看看 在这里,.他们的关键见解是,给予一块密码n位的长度,可以使用'折'缩短到m < n位,然后招antti.huima已经提到,以生成一个更小的排列从它没有花费大量的时间丢弃的范围值。

基本上你需要的是一个随机数发生器,产生的数字,0..n-1,正是曾经的每一个。

这里的一半生不熟的想法:你可以做得很好选择一个总理p略大于n,然后拿一个随机x1和p-1的顺序在乘组mod p p-1(随机挑选xs和测试哪些满足x^我!= 1为我 < p-1,你只需要测试一些你之前找到一个)。由于x然后生成的小组,就计算x^我mod p1 <=我 <=p-2,这会给你个p-2不同的随机(ish)之间的数字2和p-1.减去2扔出>=n和那个给你一个序列的索引的印刷品。

这是不是非常随机的,但你可以使用的同一技术的多次,如果索引述(+1),并利用他们作为指数的另一个发电机x2模的另一个主要p2(你会需要的n < p2 < p),等等。十几次重复应该做的事情很随意。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top