현대 버전의 fisher yates가 가장 편향적 인 셔플 알고리즘이라고 할 수 있겠습니까? 배열의 각 요소가 원래 자리에 1/n 확률이 있다고 설명 하시겠습니까?피셔가 왜 가장 유용한 셔플 알고리즘을 사용합니까?
답변
제 (현대, 일명 "크 누스 ') Fisher–Yates 셔플입니다
- 시간과 O를 위해
- 매우 효율적인 O (n)을 구현하는 비교적 간단한 (1) 또는 실제로 O (0) 공간
- 편파 (모든 순열은 동일 확률 임)
- 잘 알려져 있거나 잘 알려져 있으며, 입증 된 바 있습니다.
다른 알고리즘에서 원하는 것은 무엇입니까? (물론, 순열 수가 커지면 다른 것을 시도 할 수도 있지만 대부분의 경우 이러한 거대한 계산을 포함하지 않습니다)?
편집 : 은 그냥이 답변은 질문이 아니라 그 내용의 제목에 응답 것으로 나타났습니다. 특정 RNG는 알고리즘을 구현하는 데 사용으로 간단히 말해서
가, 셔플은 무작위 될 것입니다 (이 질문이 두 부분이 더 일치 할 필요가 좋은 이유 어떤 ...)입니다.
직관적 인 설명은 m 요소가있는 배열의 경우 루프의 감소 제어 변수가 1로 내려 가더라도 위치 n에있는 셀이 감소 할 수있는 가능한 셀,이 매우 세포가 쉽게 같은 비율로 증가 이동되었습니다. 즉, 배열의 마지막 요소는 배열의 어느 위치에서나 끝날 수 있지만 첫 번째 반복에서 이동할 수있는 기회는 단 한 번뿐입니다. 이동할 두 번째 요소부터 마지막 요소까지 이동해야 할 곳이 하나 더 적지 만 1/m의 확률로 첫 번째 반복 과정에서 쉽게 이동할 수 있습니다.
마지막 줄에 "완벽한"임의성의 이유가 즉시 설명되었습니다! :) –
완벽한 의사 난수 생성기 (Mersenne Twister 매우 가깝습니다)가 주어지면 Fisher-Yates 알고리즘은 모든 순열이 동일한 확률로 발생한다는 점에서 완전히 편파적입니다. 이것은 유도를 사용하여 증명하기 쉽습니다. 피셔 - 예이츠 알고리즘 (파이썬 구문 의사 코드)은 다음과 같이 반복적으로 기록 될 수있다 :
def fisherYatesShuffle(array):
if len(array) < 2:
return
firstElementIndex = uniform(0, len(array))
swap(array[0], array[firstElementIndex])
fisherYatesShuffle(array[1:])
각 인덱스 firstElementIndex
로서 선택되는 동일한 확률을 갖는다. 당신이 재귀 할 때, 당신은 지금 여전히 남아있는 요소를 선택할 확률이 같습니다.
편집 : 알고리즘 수학적 편견 것으로 입증되었습니다. 알고리즘이 비 결정적이므로 구현이 올바르게 작동하는지 테스트하는 가장 좋은 방법은 통계적입니다. 나는 임의적이지만 작은 크기의 배열을 취해서 여러 번 차례로 섞어서 (각 입력과 동일한 순열로 시작) 각 출력 순열이 발생하는 횟수를 계산합니다. 그런 다음 Pearson's Chi-square Test을 사용하여이 분포를 균일하게 테스트하십시오.
감사합니다 dsimcha. 어부의 셔플 구현을 테스트하고 프로그램 적으로 편향되어 있지 않다는 것을 어떻게 증명하겠습니까? 오히려 제 질문은 가장 좋은 테스트 방법입니다. – Phoenix
- 1. 가장 효율적인 배열 셔플
- 2. .NET에서 DES 알고리즘을 어떻게 사용합니까?
- 3. MySQL은 어떤 정렬 알고리즘을 사용합니까?
- 4. 가장 유용한 Python 모듈
- 5. 무작위 셔플?
- 6. Ruby의 정렬 방법은 어떤 알고리즘을 사용합니까?
- 7. 파이썬은 fractions.gcd()에서 어떤 알고리즘을 사용합니까?
- 8. PHP는 어떤 종류의 정렬 알고리즘을 사용합니까?
- 9. JPEG는 행 주요 압축 알고리즘을 사용합니까?
- 10. .NET의 Array.Sort() 메서드는 어떤 정렬 알고리즘을 사용합니까?
- 11. MsOffice는 파일 암호화에 어떤 알고리즘을 사용합니까?
- 12. in_array()는 이진 검색 알고리즘을 사용합니까?
- 13. 왜 mongoDB가 objectID를 사용합니까?
- 14. 왜 mysqli_close()를 사용합니까?
- 15. 왜 Dispatcher.BeginInvoke를 사용합니까?
- 16. 왜 Heroku는 Postgresql을 사용합니까?
- 17. 왜 Mocking Framework를 사용합니까?
- 18. 왜 is_safe를 사용합니까?
- 19. 왜 MEMCACHED_BEHAVIOR_NOREPLY를 사용합니까?
- 20. 왜 JCL UNITVERSIONING을 사용합니까?
- 21. 왜 IEditableCollectionView를 사용합니까?
- 22. Android : 왜 XMLReader를 사용합니까?
- 23. 가장 유용한 MSVC++ 비표준 매크로
- 24. 가장 흥미롭고 유용한 Java 클래스?
- 25. 가장 유용한 ASP.NET 구성 요소
- 26. 가장 유용한 탐색기 셸 확장
- 27. 왜 OpenGL은 라디안 대신도를 사용합니까?
- 28. "파괴적인"jQuery 셔플 문제
- 29. SimpleAudioEngine 셔플 재생 목록
- 30. 랜덤 셔플 동작
http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle? – pajton
@pajton : 우수 답변 +1) – Frunsi
나는 '가장 편향적'일 수있는 것이 확실하지 않습니다.그것이 편파적이라면 뒤섞기 결과가가는 한 다른 편향 알고리즘과 동일합니다. (여전히 시간, 공간 등에서 다를 수 있습니다) – Dusty