循环内的独立随机混洗

时间:2014-12-18 13:27:52

标签: python loops random shuffle

我使用模块random来混洗n元素数组。我需要m次这样做,而且我并不完全确定每次发生的洗牌都是独立的。

见下面的例子:

for i in range(10):
    a = list(range(1,20))
    random.shuffle(a)
    print("\n\nSequence of numbers ")
    for item in a:
        print(item)

我可以完全确定shuffle列表a第二次与第一次完全独立吗?

观察结果我的印象是输出不是独立的。但也许这只是我的印象。

例如,我获得的4个数字和4个重复的输出是以下[1,3,2,4],[1,3,2,4],[4,1,3,2]和[1,4,3,2]。这是偶然发生的吗?可能是。但我想确定。

背景:可能是我想订购我给予学生的考试问题。但我希望这个过程是为每个学生独立完成的。

3 个答案:

答案 0 :(得分:1)

你可以测试一下。请注意,数字1,2,3,4正好有4!= 24 个排列。您可以预期,在随机抽样中,每种排列都会同样出现。为了向自己证明这会产生您正在寻找的均匀分布,请对序列进行采样:

import random, math
from collections import Counter

samples = 1000000

a = list(range(1,5))
C = Counter()

for _ in xrange(samples):
    random.shuffle(a)
    C[tuple(a)] += 1

import pylab as plt
permutations = math.factorial(4)
expected = float(samples)/permutations
plt.plot(C.values())
plt.plot([0,permutations],[expected,expected],'r--')
plt.ylim(0,expected*2.01)   
plt.show()

enter image description here

请注意,红色破折号是理论预期值,蓝线是我们从采样中获得的值。由此我非常有信心我们得到了统一的分布,但我们总是可以用Kolmogorov Smirnov test来量化它。这个没有测试的是序列之间的相关性。这也可以使用一些时滞生成的序列对进行测试,但是pythons random.shuffle使用的Fisher-Yates shuffle在防止这种情况方面做得很好。

答案 1 :(得分:0)

出于实际目的,对random.shuffle的连续调用是独立的。它需要log(N!)/ log(2)位状态来描述元素的唯一排序,并且快速检查random.getstate()表明默认的伪随机数生成器实际上使用20000位状态。为了达到有意义的重叠,我们需要消耗所有这些熵。

因此我们需要M * log(N!)/ log(2)> = 20000来获得已知(但非常难以预测)的相关性。这不是不可想象的;它为200名学生提供了大约28个问题。然而,这种相关性的可能性超过了他们有304888344611713860501504000000可能排序的事实。

答案 2 :(得分:0)

这是来自Python random模块的实际代码:

for i in reversed(xrange(1, len(x))):
    # pick an element in x[:i+1] with which to exchange x[i]
    j = _int(random() * (i+1))
    x[i], x[j] = x[j], x[i]

对我来说看起来像是一个合适的Fisher-Yates,完全独立于 任何以前的运行。