2010-09-10 6 views
5

J'essaie de choisir aléatoirement, par ex. 4 chiffres. J'ai besoin de comparer la probabilité de ces 2 algorithmes.Probabilité de nombres aléatoires

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 

Ai-je raison si je pense qu'il est le même? La probabilité de déclaration1 dans le premier code est de 1/4 et dans le deuxième code, elle est de 250/1000 donc c'est 1/4 aussi. Mais quelqu'un m'a dit quand j'utilise une plus grande gamme de nombres aléatoires comme dans le code 2 # c'est statistiquement plus précis. J'ai fait un projet qui répète plusieurs fois ces codes, mais je ne suis pas sûr que cela me montre des résultats.

+1

Side note, vous voulez probablement ajouter des clauses d'autre à vos ifs. Pas besoin d'évaluer les 4 options une fois que vous avez réussi. –

Répondre

3

Ils sont exactement équivalents (sauf que le premier ne compilera pas en raison de l'utilisation de = au lieu de == dans les clauses if).

Pour le prouver, regardez l'implémentation de Random.Next(int, int). Avec vos valeurs, Random.Next(0, 4) est

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

et

Random.Next(0, 1000) est

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

, où Random.Sample() est une méthode privée qui renvoie un double aléatoire.

Il devrait être facile de voir que Random.Next(0, 4) retournera 0 exactement quand Random.Next(0, 1000) retournera un nombre compris entre 0 et 250.

+0

Il pourrait compiler, mais il ne ferait certainement pas ce que vous le souhaitez. – Live

+2

@Live, ce n'est pas vrai dans C#. Il ne compilera pas et produira l'erreur du compilateur: "ne peut pas implicitement convertir le type 'int' en 'bool'" –

+0

Excellent pour l'approche de la preuve. –

2

numéros de pseudo-aléatoires devrait être régulier, peu importe ce que la plage est. Si, dans votre deuxième exemple, si vous choisissez simplement les 4 derniers bits (a & 3), vous obtiendrez la même distribution que si vous choisissez les 4 suivants avec (a>>2) & 3. C'est à dire. Ce que vous faites algorithmiquement dans le second exemple en utilisant des plages, c'est en ignorant beaucoup d'informations que le générateur aléatoire vous a donné. Vous n'obtenez plus de "hasard" avec une plus grande portée. Cela dit, les générateurs pseudo-aléatoires ont leurs particularités, mais si vous n'êtes pas sérieux à ce sujet, cela ne vaut pas la peine de vous inquiéter!

0

La distribution est uniforme et il est facile de vérifier:

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

Mes tests sont les suivants

Sur une boucle 10K 2 essais a été exécuté avec une gamme 1-4 et une gamme 1-1000, Heres la résultats

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 

ma conclusion est qu'ils ne font aucune différence que si jamais, vous devez entrer dans de matrice et ainsi de suite d'avoir un certain contrôle sur la génération de nombres aléatoires et ainsi de suite.

Note: mes tests ont été réalisés avec PHP et le code source est ci-dessous.


<?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 Il est trop important de dire que l'implémentation de l'implémentation du nombre aléatoire php est identique à celle utilisée par C# –

Questions connexes