2010-01-23 4 views
4

10 정수의 목록은 10입니다! 가능한 명령 또는 순열. random.shuffle이 5000 번 시도한 후에 중복을주는 이유는 무엇입니까?왜 random.shuffle을 사용하여 dups를 파이썬으로 구할 수 있습니까?

>>> 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 = (! 1 - 10)/10! 이고 조합 수는 C = 5000!/4998! * 2! = 5000 * 2분의 4,999 는 중복을 가질 확률은 다음과 같습니다

>>> import math 
>>> f = math.factorial(10) 
>>> p = 1.0*(f-1)/f 
>>> C = 5000.0*4999/2 
>>> 1 - p**C 
0.96806256495611798 
+4

당신의 대답은 –

+4

입니다. Birthday Paradox (google it)로 인해, N 가능성 중에서 선택된 N ** 0.5 항목 사이에서 중복 가능성이 높습니다. 여기서 N = 10! (10!) ** 0.5 ~ = 1900 시도 후에 dups를 예측합니다. 반복을 피하는 코드는 http://stackoverflow.com/questions/2124347/how-to-generate-permutations-of-array-in-python/2124365#2124365를 참조하십시오. –

+0

고마워요. 나는 실제로 생일 Paradox를 알고있다. 그러나 그것을 할인했다. 나는 DUP의 50 %의 기회를 얻기 위해 N ** 0.5 의존성을 인식하지 못했습니다. – telliott99

답변

19

Birthday Paradox이라고합니다. 위키 백과에서이 공식에 따르면

:

하지만 10!으로 365 대체 당신은 충돌의 50 %의 확률로 약 2,200 예를 만 필요하고, 그 위의 방법입니다.

+3

수치를 계산해 보면 3628800 세트에서 5000을 선택할 때 별개의 값이 3 % 정도 나올 확률을 보여줍니다. 결과에서 세트를 구성하면 97 %의 확률로 5000보다 적은 것을 얻으십시오. – Autoplectic

6

그건 때문에 ... 임의! 모든 순열을 원하면 itertools.permutations를 사용하십시오.

2

아마 RANDOM입니까? 무작위 란 반복하지 않는다는 것을 의미하지는 않으며, 이론적으로 매번 정확한 답변을 반환 할 수 있음을 의미하는 RANDOM을 의미합니다.

+0

"무작위로 문제가 있는데, 정말 확신 할 수 없어요!" –