【问题标题】:Why am I getting dups with random.shuffle in Python?为什么我在 Python 中使用 random.shuffle 得到重复?
【发布时间】: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


【解决方案1】:

它被称为Birthday Paradox

根据维基百科的这个公式:

但是将365 替换为10!,您只需要大约2200 个示例就有50% 的碰撞机会,而且您远远高于此。

【讨论】:

  • 如果你对数字进行处理,表明从一组 3628800 中选择 5000 时,只有大约 3% 的机会获得 5000 个不同的值。所以当你构建一个从你的结果中设置你会得到少于 5000 的东西。
【解决方案2】:

因为它是……随机的!如果您想要所有排列,只需使用 itertools.permutations。

【讨论】:

    【解决方案3】:

    也许是因为是随机的?随机不代表不重复,而是随机,也就是说理论上每次都可以返回完全相同的答案,不太可能但有可能。

    【讨论】:

    • “那是随机的问题;你不能确定!”
    猜你喜欢
    • 2020-02-28
    • 1970-01-01
    • 2021-03-10
    • 2018-05-11
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 2020-12-21
    相关资源
    最近更新 更多