【发布时间】:2011-01-08 15:30:23
【问题描述】:
对于 10 个整数的列表,有 10 个!可能的顺序或排列。为什么 random.shuffle 仅在 5000 次尝试后给出重复项?
>>> L = range(10)
>>> rL = list()
>>> for i in range(5000):
... random.shuffle(L)
... rL.append(L[:])
...
>>> rL = [tuple(e) for e in rL]
>>> len(set(rL))
4997
>>> for i,t in enumerate(rL):
... if rL.count(t) > 1:
... print i,t
...
102 (7, 5, 2, 4, 0, 6, 9, 3, 1, 8)
258 (1, 4, 0, 2, 7, 3, 5, 9, 6, 8)
892 (1, 4, 0, 2, 7, 3, 5, 9, 6, 8)
2878 (7, 5, 2, 4, 0, 6, 9, 3, 1, 8)
4123 (5, 8, 0, 1, 7, 3, 2, 4, 6, 9)
4633 (5, 8, 0, 1, 7, 3, 2, 4, 6, 9)
>>> 10*9*8*7*6*5*4*3*2
3628800
>>> 2**19937 - 1
431542479738816264805523551633791983905393 [snip]
>>> L = list()
>>> for i in range(5000):
... L.append(random.choice(xrange(3628800)))
...
>>> len(set(L))
4997
编辑:FWIW,如果一对没有两个相同的概率是: p = (10! - 1) / 10! 组合数为: C = 5000! /4998! * 2! = 5000 * 4999 / 2 那么出现重复的概率是:
>>> import math
>>> f = math.factorial(10)
>>> p = 1.0*(f-1)/f
>>> C = 5000.0*4999/2
>>> 1 - p**C
0.96806256495611798
【问题讨论】:
-
xkcd.com/221 这就是你的答案 :) -
由于生日悖论(google it),从 N 个可能性中选择的 N**0.5 个项目中重复的概率很高。这里N=10!预测 (10!)**0.5 ~= 1900 次尝试后的重复。有关避免重复的代码,请参阅 stackoverflow.com/questions/2124347/…。
-
谢谢大家。我实际上知道生日悖论,但不以为然。我不喜欢 N**0.5 的依赖来获得 50% 的重复机会。
标签: python random probability birthday-paradox