2010-09-10 28 views
5

Estoy tratando de elegir al azar, p. Ej. 4 números. Necesito comparar la probabilidad de estos 2 algoritmos.Probabilidad de números aleatorios

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 

Estoy en lo cierto si pienso que es lo mismo? La probabilidad de la declaración1 en el primer código es 1/4 y en el segundo es de 250/1000, por lo que también es 1/4. Pero alguien me ha dicho que cuando uso un rango más grande de números aleatorios como en el código 2 # es estadísticamente más preciso. He hecho un proyecto que repite muchas veces esos códigos, pero no estoy seguro de que me muestre algunos resultados.

+1

Nota al margen, es probable que desee agregar cláusulas más que sus IFS. No es necesario evaluar las 4 opciones una vez que haya tenido éxito. –

Respuesta

3

Son exactamente equivalentes (excepto por el hecho de que el primero no se compilará debido al uso de = en lugar de == en las cláusulas if).

Para comprobar esto, consulte la implementación de Random.Next(int, int). Con sus valores, Random.Next(0, 4) es

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

y

Random.Next(0, 1000) es

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

, donde Random.Sample() es un método privado que devuelve un doble al azar.

Ahora debería ser fácil de ver que Random.Next(0, 4) devolverá 0 exactamente cuando Random.Next(0, 1000) devolverá un número entre 0 y 250.

+0

Podría compilar, pero ciertamente no haría lo que usted quisiera. – Live

+2

@Live, eso no es cierto en C#. No se compilará y generará el error del compilador: "no se puede convertir implícitamente el tipo 'int' a 'bool'" –

+0

Estupendo para el enfoque de la prueba. –

2

números pseudoaleatorios debe distribuirse uniformemente sin importar el rango es. Si, en su segundo ejemplo, si elige los últimos 4 bits (a & 3), obtendrá la misma distribución que si elige los siguientes 4 con (a>>2) & 3. Es decir. lo que está haciendo algorítmicamente en el segundo ejemplo utilizando intervalos, es descartando mucha de la información que el generador aleatorio le ha dado. No obtienes más "aleatoriedad" con un rango mayor.

Habiendo dicho esto, los generadores pseudoaleatorios tienen sus idiosincracias, ¡pero a menos que usted se lo tome en serio, no vale la pena preocuparse por ello!

0

La distribución es uniforme y es fácil de verificar:

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

Mis pruebas son las siguientes

de salida de un circuito de 10K 2 pruebas se realizó con una gama 1-4 y una gama 1-1000, aquí está el resultados

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 

mi conclusión es que no hacen ninguna diferencia lo que nunca, hay que entrar en la matriz de y así sucesivamente a tener cierto control sobre la generación de números aleatorios y así sucesivamente.

Nota: mis pruebas se realizaron con PHP y el código fuente está a continuación.


<?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 Es una suposición demasiado grande para decir que la implementación de la implementación del número aleatorio php es idéntica a la utilizada por C# –