2010-09-10 14 views
5

Próbuję losowo wybierać z np. 4 cyfry. Muszę porównać prawdopodobieństwo tych 2 algorytmów.Losowe prawdopodobieństwo liczb

1 #

   int a = random.Next(0, 4); 

       if (a = 0) 
        statement1 
       if (a = 1) 
        statement2 
       if (a = 2) 
        statement3 
       if (a = 3) 
        statement4 

2 #

   int a = random.Next(0, 1000) 

       if (a < 250) 
        statement1 
       if (a >= 250 && a < 500) 
        statement2 
       if (a >= 500 && a < 750) 
        statement3 
       if (a >= 750) 
        statement4 

mam rację, jeśli myślę, że to jest to samo? Prawdopodobieństwo wystąpienia instrukcji1 w pierwszym kodzie wynosi 1/4, a w drugim kodzie jest to 250/1000, więc również 1/4. Ale ktoś powiedział mi, kiedy używam większego zakresu liczb losowych, jak w kodzie 2 #, jest statystycznie dokładniejszy. Zrobiłem projekt, który powtarza wiele razy te kody, ale nie jestem pewien, czy pokazuje mi jakieś wyniki.

+1

marginesie, prawdopodobnie chcesz dodać klauzule innego do swoich IFS. Nie musisz wyceniać wszystkich 4 opcji, gdy już odniosłeś sukces. –

Odpowiedz

3

Są one dokładnie równoważne (z wyjątkiem faktu, że pierwszy nie skompiluje się z powodu użycia = zamiast == w klauzulach if).

Aby to udowodnić, spójrz na implementację Random.Next(int, int). Ze swoimi wartościami, Random.Next(0, 4) jest

(int) (Random.Sample() * 4) 

i

Random.Next(0, 1000) jest

(int) (Random.Sample() * 1000) 

, gdzie Random.Sample() to prywatna metoda, która zwraca losową podwójne.

Powinno być teraz łatwo zauważyć, że Random.Next(0, 4) powróci 0 dokładnie gdy Random.Next(0, 1000) zwróci liczbę między 0 a 250.

+0

Może się skompilować, ale z pewnością nie zrobi tego, czego byś chciał. – Live

+2

@ Live, to nie jest prawda w języku C#. Nie skompiluje się i wygeneruje błąd kompilatora: "nie można niejawnie przekonwertować typu" int "na" bool "" –

+0

Świetne podejście do podejścia opartego na dowodach. –

2
liczb pseudolosowych

powinny się równomiernie bez względu na zakres jest. Jeśli w twoim drugim przykładzie, jeśli wybierzesz tylko 4 ostatnie bity (a & 3), otrzymasz taką samą dystrybucję, jak w przypadku wybrania następnych 4 z (a>>2) & 3. To znaczy. to, co robisz algorytmicznie w drugim przykładzie z użyciem zakresów, to odrzucając wiele informacji, które podał ci generator losowy. Nie uzyskasz więcej "losowości" z większym zakresem.

Powiedziawszy to, generatory pseudolosowe mają swoje idiosynkrazje, ale jeśli nie mówisz poważnie o tym, nie warto się tym przejmować!

0

Dystrybucja jest jednolita i jest to łatwe do sprawdzenia:

public class Program 
{ 
    static void Main(string[] args) 
    { 
     var random = new Random(); 
     const int iterations = 10000000; 

     var hits1 = 1.0 * Enumerable.Range(1, iterations) 
            .Select(i => random.Next(0, 4)) 
            .Where(i => i == 0).Count(); 
     Console.WriteLine(hits1/iterations); 

     var hits2 = 1.0 * Enumerable.Range(1, iterations) 
            .Select(i => random.Next(0, 1000)) 
            .Where(i => i < 250) 
            .Count(); 
     Console.WriteLine(hits2/iterations); 
    } 
} 
-1

moich testów są

Z pętli 10K 2 testach był prowadzony z zakresu 1-4 oraz szereg 1-1000, Herezje następująco wynika

1-4

1 > 2484 times 
    2 > 2519 times 
    3 > 2511 times 
    4 > 2487 times 

0 - 1000

1 - 250 > 2421 times 
    250 - 500 > 2531 times 
    500 - 750 > 2529 times 
    750 - 1000 > 2490 times 

moja konkluzja jest taka, że ​​robią żadnej różnicy, co tak zawsze, trzeba dostać się matryca i tak dalej, aby mieć kontrolę nad generatorów liczb losowych i tak dalej.

Uwaga: moje testy zostały wykonane przy użyciu PHP, a kod źródłowy znajduje się poniżej.


<?php 

$first = array(1=>0,2=>0,3=>0,4=>0); 
$second = array('0 - 250' => 0, '250 - 500' => 0, '500 - 750' => 0,'750 - 1000' => 0); 

for($i=0;$i<=10000;$i++) //10K 
{ 
    //First 
    $f_number = rand(1,4); 
    switch($f_number) 
    { 
     case 1: $first[$f_number]++; break; 
     case 2: $first[$f_number]++; break; 
     case 3: $first[$f_number]++; break; 
     case 4: $first[$f_number]++; break; 
    } 

    //Second 
    $s_number = rand(1,1000); 
    if($s_number < 250) $second['0 - 250']++; 
    if($s_number > 250 && $s_number < 500) $second['250 - 500']++; 
    if($s_number > 500 && $s_number < 750) $second['500 - 750']++; 
    if($s_number > 750) $second['750 - 1000']++; 
} 

var_dump($first,$second); 
?> 
+0

-1 Jest zbyt dużym założeniem, aby powiedzieć, że implementacja implementacji php losowej liczby jest identyczna z tą używaną przez C# –

Powiązane problemy