2009-09-18 7 views
8

나는 특정 카드를 나타내는 PlayingCard 클래스가 있습니다. PlayingCard 객체 목록이 들어있는 다른 클래스 인 Deck이 있습니다. 갑판에는 shuffle() 카드 주문을 무작위로 추출하는 방법이 있습니다.카드 덱 셔플러 테스트하기

shuffle() 메서드에 대한 단위 테스트를 작성하고 싶습니다만, 약간 손실이 있습니다. 셔플이 완료된 방법에 대해 내부적으로 신경 쓰지 않는 테스트를 선호하지만 테스트를 잘 수행하고 싶습니다.

임의성이 관련되어있을 때 단위 테스트를 가장 잘하려면 어떻게해야합니까?

+1

하나의 아이디어는 정렬 된 데크에서 셔플 러를 실행하고 거리 알고리즘을 실행하여 셔플이 멀리 떨어져있는 것을 확인하는 것입니다. (즉, 거리 요구 사항을 저하시키는 10-12 개의 셔플) 이전의 순열과 비교하여 그 값을 최적의 차이와 비교하십시오. 테스트를 거쳐 그 숫자를 직접 얻어야합니다. – Corazu

답변

10

하나의 접근법은 통계 테스트를 만드는 것입니다. 카드의 세트 세트를 변경하지 말고 주문 만 변경하면 안된다. 임의의 임의의 변수에 대한 통계를 수집한다 ("다이아몬드 7 개 위치", "전후 5 개 클럽" 8 개의 하트 "등)을 Student's t-test 및 다른 통계 가설 테스트 접근법에 의해 적절한 수의 셔플 후에 테스트 할 수있다.

+0

좋습니다. –

+0

Tx @Ty, 그래서 당신이 그것을 좋아한다면 왜 upvote? -) –

0
  1. 목록을 만듭니다.
  2. 해당 목록의 전체 복사본을 만듭니다.
  3. 첫 번째 목록을 섞습니다.
  4. 어설의 목록 1! =리스트 2

당신이 필요로 더 자세한 설명 테스트를 추가합니다. 셔플, 임의성 등의 품질 ...

Alex Martelli는 지적한대로 정렬에 대한 통계 분석을 수행하여 원하는 정도로 정렬되었는지 확인할 수 있습니다.

최상의 결과는 모든 카드 위치가 변경된다는 것입니다. 의미, 52 카드의 모든 하나는 이제 새로운 위치에 있습니다. 위의 방법을 사용하고 다른 요소의 수를 기록하고 테스트의 기준점을 설정할 수 있습니다.

적어도 20 개의 카드가 새로운 위치에 있어야합니다. 목록을 만들고 복사 한 다음 정렬하고 비교합니다. 결과가 20보다 작 으면 실패하고 그렇지 않으면 통과합니다.

+0

셔플 후 순서가 동일 할 가능성이 있습니다. –

+0

셔플이 주어진 동일한 목록을 반환 할 확률이 p라고합시다. 그런 다음 시간의 100 % -이 테스트는 올바르게 작동합니다. 당신이하는 일에 상관없이, 항상 p가있을 것입니다. 실패하면 다시 실행하여 작게 만들 수 있지만 더 많은 테스트 시간이 소요됩니다. 일반적으로 나쁜 것으로 간주됩니다. –

1

좋은 질문입니다. 첫째, 절대 합격/불합격 테스트 : 셔플 후 다중 정렬 (예 : 정렬 후 비교)이 변경되지 않아야합니다.

임의성을 테스트하려면 잘못된 "충분하지 않은 임의적 인"오류가 발생할 가능성이 거의 없으므로 충분한 셔플을 수행해야합니다. 예 :

특정 카드가 (1-e)/52보다 작거나 (1 + e) ​​/ 52보다 큰 주어진 슬롯에 10000 개 셔플 중에 10000 %의 확률로 존재할 확률이 있습니다. . (어떤 작은 e를 위해, 나는 그것을 계산하는 방법을 잘 모른다.)

올바른 프로그램은 이러한 테스트에 "실패"하지만 매우 자주 실패하지 않아야합니다.

셔플 링과 관련하여; 1..52에서 내가 대한

: 하나 개의 공통 실패는이 작업을 수행하는 것입니다
1에서 임의의 J를 선택합니다 ..52 카드 j를 카드 i와 교환하십시오 (틀린)

그렇다고해서 똑같은 확률로 어떤 순열도 나오지는 않습니다. 그러나 이것은 수행합니다

내가 1..52에서 위해 :
나는 '돈 임의의 에서 J 난 ..52 및 스왑 카드 I와 (오른쪽) 카드 J

5

을 선택 단위 테스트에 대한 특별한 아이디어가 있지만 사용하는 알고리즘에 대한 빠른 참고가 있습니다. 순진하고 무의식적으로 편향된 셔플 알고리즘을 만드는 것은 매우 쉽습니다. 휠을 재발견 할 필요가 없습니다. Fisher-Yates shuffle은 올바르게 구현 된 경우 편향 셔플을 보장합니다.

제대로 FY을하지 않으면 당신이 공격 할 수 쉬운 함정이 있습니다

  • 내가을 각각의 카드를 가지고 갑판에 또 다른 임의의 카드로 J 그것을 교환 어디 J 수 이미 방문한 직책의 카드 일 수도 있습니다. 이 은 편향 셔플 인입니다.
  • RNG mod 52의 출력을 사용하여 임의의 카드 위치를 가져옵니다. 또한 약간의 편견이 생깁니다.
-2

나는 이것을 실제로 시도하지는 못 했으므로 실용적인 방법은 말할 수 없지만 작은 데크와 특수 결정 성 난수 생성기를 사용하여 단위 테스트를 할 수 있어야하며 셔플 러는 각 가능한 순열을 한 번 생성해야합니다.

1

몇 년 전에 야후 그룹 TDD 목록에 철저한 주제 (소진 상태)가있었습니다. Ron Jeffries는 useful insights가 있지만 the top부터 시작하는 것이 가장 좋습니다.

5

목표는 shuffle()을 테스트하는 것입니다. shuffle()을 어떻게 생성했는지 알았으므로 생성 된 일련의 숫자를 알 수 있다면 초기 데크 대 셔플 데크의 결정적 단위 테스트가됩니다.

테스트 중에 메서드를 사용자의 Deck() 클래스에 삽입하면 셔플 함수가 결정적 일 수 있습니다.

기본적으로 random() 함수를 사용하도록 클래스를 작성하지만 주입시 미리 결정된 숫자 생성 함수를 사용하십시오. 예를 들어, 파이썬에서는 다음을 할 수 있습니다 :

class Deck(): 
    def __init__(self, rand_func = random.random): 
     self._rand = rand_func 
    def rand(self): 
     return self._rand() 

단순히 덱을 인자없이 사용하면 예상되는 난수를 얻게됩니다. 그러나 자신의 난수 함수를 만들면 미리 정해진 수열을 생성 할 수 있습니다.

이 구조를 사용하면 초기 데크 (원하는 크기)와 난수 목록 (다시 원하는 크기)을 작성할 수 있으며 출력으로 기대되는 것을 알 수 있습니다. 주입 된 버전과 진정한 랜덤 버전 사이에서 shuffle()이 변경되지 않으므로 런타임에 결정적으로 shuffle() 테스트 유닛을 테스트 할 수 있습니다. 테스트하려는 구석이있는 경우 여러 개의 숫자 시퀀스를 생성 할 수도 있습니다.

통계 모델링을 포함하는 다른 답변에 대해서는 다음과 같습니다. "shuffle"알고리즘의 정확성을 입증하는 승인 수준 테스트라고 생각하지만 기능 shuffle()의 구현을 결정적으로 테스트하지는 않습니다.