Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何随机洗牌比PRNG'有更多排列的列表;月经期?_Python_Algorithm_Random - Fatal编程技术网

Python 如何随机洗牌比PRNG'有更多排列的列表;月经期?

Python 如何随机洗牌比PRNG'有更多排列的列表;月经期?,python,algorithm,random,Python,Algorithm,Random,我有一个包含大约3900个元素的列表,我需要随机排列这些元素以生成统计分布。我环顾四周,发现这解释了Python中PRNG的周期是2**19937-1,这导致在无法生成所有可能的排列之前,列表的最大长度是2080。我只生成列表的300-1000个排列,因此不太可能生成重复排列,但是,由于这是一个统计分布,我希望所有可能的排列都作为潜在样本 有比MT更长的周期PRNG,但它们很难找到 要得到全部3090!组合,你需要40905位的熵。大约5公里。您应该能够多次从random.org之类的地方获取大

我有一个包含大约3900个元素的列表,我需要随机排列这些元素以生成统计分布。我环顾四周,发现这解释了Python中PRNG的周期是
2**19937-1
,这导致在无法生成所有可能的排列之前,列表的最大长度是
2080
。我只生成列表的300-1000个排列,因此不太可能生成重复排列,但是,由于这是一个统计分布,我希望所有可能的排列都作为潜在样本

有比MT更长的周期PRNG,但它们很难找到


要得到全部3090!组合,你需要40905位的熵。大约5公里。您应该能够多次从random.org之类的地方获取大小相同的字节块,而不会有任何问题。要获得精确的平衡,您必须添加一些并进行拒绝采样。即,一次获取12位(0..4095),并拒绝高于当前循环索引的数字。这可能会增加所需的位数,但可能不会超过8kb。

我同意@user2357112的观点,即这不太可能是一个真正的问题——但似乎您应该能够使用标准的
随机
模块,使所有排列至少都是可能的

你可以采取分而治之的方法。使用初始种子将列表划分为2个列表,每个列表大约2000个。此类分区的数量大致为
C(40002000)
,约为
1.66 x 10^1202
。这比周期要短,这表明至少可以使用
random.sample()
生成所有此类分区。然后重新设定随机数生成器的种子,并排列前半部分。然后——第二次重新设定种子并排列下半部分。也许在重新设定之前会有一些时间延迟,这样您就不会遇到涉及系统时钟分辨率的问题。您还可以尝试将初始列表随机划分为大量较小的列表

从数学上讲,很容易看出,如果你随机将一个列表划分为子列表,使每个分区的可能性相等,然后你对每个子列表进行排列,使所有子列表排列的可能性相等,并将这些子列表排列粘在一起,得到一个完整的列表排列,那么所有的列表排列都是同样可能的

下面是一个实现:

import random, time

def permuted(items, pieces = 2):
    sublists = [[] for i in range(pieces)]
    for x in items:
        sublists[random.randint(0,pieces-1)].append(x)
    permutedList = []
    for i in range(pieces):
        time.sleep(0.01)
        random.seed()
        random.shuffle(sublists[i])
        permutedList.extend(sublists[i])
    return permutedList
我不确定是否真的需要
时间。睡眠(0.01)
。我担心的是,如果种子在毫秒内重新播种,那么在某些系统上可能会使用相同的种子


最后一句话,仅仅因为上面的函数(通过适当选择
片段
)不能通过简单的计数参数(比较置换的数量和初始状态的数量)来显示错过某些置换,这本身并不能证明所有置换实际上都是可能的。这需要对随机数生成器、它的种子散列函数和洗牌算法进行更详细的分析

您想生成3900个元素的所有可能排列吗?您是否考虑过使用
os.uradom
?Uradom适用于加密,所以我认为无论你在做什么,它都应该适用。出于统计目的——事实上,基本上是出于任何目的——对可能的排列的限制不是问题。如果你担心这一点,你就要担心与理想分布的更大偏差。作为“更大偏差”的一个例子,同样,对于建议加密PRNG的人来说,即使那些PRNG也没有时间产生所有可能的排列,甚至密码学家也不关心。@m69不,它只会给你一套不同的2^19937。如果您第二次使用不同的PRNG进行排列,在最好的情况下,您可以添加它们的周期(如果它们之间没有交互)。这似乎是一个非常好的解决方案。您能提供一个随机划分原始列表的代码示例吗?