2014-11-26 2 views
2

2 일 동안 머리를 긁어 내 코드에 무엇이 잘못된 것인지 알 수 없습니다.배열에서 특정 번호를 선택하는 확률

Array1[33]: 0..31 (it has 2 fives) 
Array2[32]: 0..31 (it has one five) 

가 지금은 무작위로 두 번째 배열에서 첫 번째 배열에서 5, 5를 따기의 확률을 계산하려면 : 나는 두 배열을 가지고 있다고 할 수 있습니다. 이 공식으로이 작업을 수행합니다.

(2M/33) * (1M/32) 

대략적으로 0.001894입니다. 이제 사이클을 충분히 오래 실행하면 1000,000,0이라고 말하면서 '5' '5'가 대략 18940 번 올 것이라고 예상해야합니다. 그러나 테스트를 실행할 때 이런 일은 발생하지 않습니다. 여기 코드는 : 그것은 두 배나 많은 시간을 마련해야 할 때

public class Program 
{ 
    private static List<int> numbers1 = new List<int>(); 
    static Random random = new Random(Guid.NewGuid().GetHashCode()); 
    private static List<int> numbers2 = new List<int>(); 

    static void Main(string[] args) 
    { 
     for (int i = 0; i < 33; i++) 
     { 
      numbers1.Add(i); 
      numbers2.Add(i); 
     } 

     numbers1.Add(5); 

     while (true) 
     { 
      var counter = 0; 
      for (int i = 0; i < 10000000; i++) 
      { 
       var num1 = numbers1[random.Next(0, 33)]; 
       var num2 = numbers2[random.Next(0, 32)]; 

       if (num1 == 5 && num2 == 5) counter++; 
      } 

      Console.Write(counter + ": " + (decimal) counter/10000000 + " - " + (2M/33) * (1M/32)); 
      Console.ReadLine(); 
     } 
    } 
} 

패턴은 '5'5 '는'어디 선가 9300-9500 번 온다.

제 질문은 내 수학/코드가 잘못 되었나요?

감사

편집 : 나는 단지 1 ~ 5 첫 번째 배열에두면, 모든 것이 예상 작동하기 때문에 것을

참고.

//numbers1.Add(5); 

    while (true) 
    { 
     var counter = 0; 
     for (int i = 0; i < 10000000; i++) 
     { 
      var num1 = numbers1[random.Next(0, 33)]; 
      var num2 = numbers2[random.Next(0, 32)]; 

      if (num1 == 5 && num2 == 5) counter++; 
     } 

     Console.Write(counter + ": " + (decimal) counter/10000000 + " - " + (1M/33) * (1M/32)); 
     Console.ReadLine(); 

이 코드를 반환 예상되는 결과

+0

왜 downvote? – Davita

+0

두 개의 별개의 랜덤 (random)으로 동일한 결과를 얻었 을까? – SimpleVar

+0

@YoryeNathan 예, 그냥 시도 : ( – Davita

답변

5

해결책은 간단합니다. 배열에 너무 많은 요소를 추가하고 있습니다.

for (int i = 0; i < 33; i++) 
{ 
    numbers1.Add(i); 
    numbers2.Add(i); 
} 

하지 32

Random.Next(a, b)[a, b) (반 개방 간격) 사이의 난수를 생성하는 어레이 33 요소를 추가한다. 따라서 random.Next(0, 33)은 0과 32 사이의 숫자를 생성합니다. numbers1에 추가되는 추가 5는 인덱스 33에 있기 때문에 검색되지 않습니다.

데이터를 작성할 때 33에서 32로 변경하면 간단하게 작동합니다.

0
은 문 while 루프의 var random = new Random(Guid.NewGuid().GetHashCode()); 외부 이동

.

매우 가까운 시간 간격으로 반복하여 Random을 다시 시드하면 결과가 왜곡됩니다.

시드 Random 귀하의 프로세스에 한 번만 사용하면 결과가 좋지 않을 수 있습니다.

+0

감사합니다, 시도했지만 동일한 결과 – Davita

+0

임의의 init 내 모든 항목을 제거하고 그냥 랜덤()을 호출하십시오 –

+1

코드를 업데이트했습니다. 무작위 클래스가 이제 정적으로 선언되고 한 번 초기화됩니다. 하지만이 같은 결과 – Davita

3

글쎄, 코드를 보면서 나는 그것을 보지 못했다. 당신이 33 가정

numbers1.Count == 34 

: 디버거 켜기 및 몇 가지 검사 나는 것을 알 수 있습니다. 더블 5가 마지막 요소입니다. 결코 그려지지 않습니다.

그런 이유로 random.Next(0, 33)과 같은 마법 번호를 쓰면 안됩니다. 대신 random.Next(0, numbers1.Count)을 사용하십시오. 이것은 코드의 다른 것들에도 적용됩니다. 반복 상수는 버그가있는 위치입니다.

+1

까지 32 개의 숫자가 있습니다. 마지막 숫자를 선택할 수있게되지만, 그의 배열은 하나 더 큽니다. 따라서 그의 백분율은 약간 떨어져 있습니다. 진짜 문제는 초기화 코드 때문입니다. –

+0

네, 맞아요. 별로 중요하지 않습니다. 문제는 지금 분명합니다. – usr

관련 문제