2012-05-23 24 views
10

He hecho tal experimento: hice 10 millones de números aleatorios de C y C#. Y luego contó cuántas veces se establece cada bit de 15 bits en entero aleatorio. (Elegí 15 bits porque C solo admite números enteros aleatorios hasta 0x7fff).Bits más probables en entero al azar

lo que tengo es la siguiente: enter image description here
tengo dos preguntas:

  1. Por qué hay 3 bits más probables? En C son más probables los bits de caso 8,10,12. Y en C# bits 6,8,11 son los más probables.

  2. También parece que C# bits más probables es mayormente desplazado por 2 posiciones y luego comparado con C bits más probables. Por qué es esto ? Porque C# usa otra constante RAND_MAX o qué?


Mi código de prueba para C:

void accumulateResults(int random, int bitSet[15]) { 
    int i; 
    int isBitSet; 
    for (i=0; i < 15; i++) { 
     isBitSet = ((random & (1<<i)) != 0); 
     bitSet[i] += isBitSet; 
    } 
} 

int main() { 
    int i; 
    int bitSet[15] = {0}; 
    int times = 10000000; 
    srand(0); 

    for (i=0; i < times; i++) { 
     accumulateResults(rand(), bitSet); 
    } 

    for (i=0; i < 15; i++) { 
     printf("%d : %d\n", i , bitSet[i]); 
    } 

    system("pause"); 
    return 0; 
} 

Y Código de ensayo para C#:

static void accumulateResults(int random, int[] bitSet) 
{ 
    int i; 
    int isBitSet; 
    for (i = 0; i < 15; i++) 
    { 
     isBitSet = ((random & (1 << i)) != 0) ? 1 : 0; 
     bitSet[i] += isBitSet; 
    } 
} 

static void Main(string[] args) 
{ 
    int i; 
    int[] bitSet = new int[15]; 
    int times = 10000000; 
    Random r = new Random(); 

    for (i = 0; i < times; i++) 
    { 
     accumulateResults(r.Next(), bitSet); 
    } 

    for (i = 0; i < 15; i++) 
    { 
     Console.WriteLine("{0} : {1}", i, bitSet[i]); 
    } 

    Console.ReadKey(); 
} 

Muy gracias !! Por cierto, el sistema operativo es Windows 7, la arquitectura de 64 bits & Visual Studio 2010.

EDITAR
Muy gracias a @ David Heffernan. Cometí varios errores aquí:

  1. La semilla en los programas C y C# era diferente (C estaba usando cero y C# - hora actual).
  2. No intenté experimentar con diferentes valores de la variable Times para investigar la reproducibilidad de los resultados.

Esto es lo que tengo cuando se analiza cómo probabilidad de que la primera bit se establece depende del número de veces al azar() se llama: enter image description here
Así como muchos notado - Los resultados no son reproducibles y no deben ser tomado en serio. (Excepto como una forma de confirmación de que C/C# PRNG es lo suficientemente bueno :-)).

+2

No puedo recordar mucho de mis clases de estadística en la escuela, pero debe averiguar si los valores atípicos son estadísticamente significativo o simplemente un resultado de error aleatorio. Nunca obtendrás una distribución perfecta. –

+3

¿Estos resultados son reproducibles? Eso me sorprendería. Si ejecuta la misma prueba varias veces, sospecho que en las siguientes ejecuciones, saldrán diferentes bits "más probable" y "menos probable". – abelenky

+0

No tengo dudas de que son reproducibles. 'rand' normalmente se implementa con una congruencia lineal PRNG, que tiene propiedades estadísticas ridículamente malas. Su mejor esperanza de obtener resultados razonables de 'rand' es usar solo un bit (el bit alto) de cada llamada, y llamarlo repetidamente ... –

Respuesta

10

Esto es solo variación de muestreo común o en el jardín.

Imagine un experimento en el que arroja una moneda diez veces, repetidamente. No esperarías obtener cinco cabezas cada vez. Eso se debe a la variación de muestreo.

De la misma manera, su experimento estará sujeto a variaciones de muestreo. Cada bit sigue la misma distribución estadística. Pero la variación de muestreo significa que no esperaría una división exacta de 50/50 entre 0 y 1.

Ahora, su trama le hace pensar erróneamente que la variación es significativa o tiene algún significado. Te obtener una mejor comprensión de esto si que dibujó el eje Y del gráfico a partir de 0. gráfica se parece a esto:

enter image description here

Si el generador de números aleatorios se comporta como debe ser, entonces cada bit siga el binomial distribution con la probabilidad 0.5. Esta distribución tiene varianza np (1 - p). Para su experimento, esto arroja una variación de 2.5 millones. Tome la raíz cuadrada para obtener la desviación estándar de alrededor de 1,500. Entonces, puede ver simplemente inspeccionando sus resultados, que la variación que ve no es obviamente fuera de lo común. Tiene 15 muestras y ninguna tiene más de 1,6 desviaciones estándar de la media real. Eso no es nada de qué preocuparse.

Ha intentado discernir las tendencias en los resultados. Usted ha dicho que hay "3 bits más probables". Esa es solo su interpretación particular de esta muestra. Intente ejecutar sus programas nuevamente con diferentes semillas para sus RNG y tendrá gráficos que se ven un poco diferentes. Ellos todavía tendrán la misma calidad para ellos. Algunos bits están configurados más que otros. Pero no habrá patrones discernibles, y cuando los traza en un gráfico que incluye 0, verá líneas horizontales.

Por ejemplo, esto es lo que su programa C genera para una semilla aleatoria de 98723498734.

enter image description here

creo que esto debería ser suficiente para persuadir a ejecutar algunas pruebas más. Cuando lo haga, verá que no hay bits especiales que reciban un tratamiento favorable.

+0

+1. Pero uno esperaría que cuando 'N' vaya al infinito, entonces la relación esperada convergería en un 50%. –

+0

@Oli Sí, pero aquí tenemos 'N' que es finito. Y entonces siempre hay variaciones de muestreo. –

+0

Gracias por muy buena explicación estadística. Sin embargo, las estadísticas no explican las "razones" del resultado del experimento concreto. Y son las razones del resultado lo que más me interesa en esta pregunta. '¿Puedo decir que la semilla exacta al azar() hace que se establezcan los bits preferidos?' (Eso explicaría la parte de Pseudorandomness "PSEUDO") –

2

¿Sabía que la desviación es de aproximadamente 2500/5,000,000, que se reduce a 0,05%?

+3

Y bajo la hipótesis de que cada bit realmente es uniformemente aleatorio, la varianza es 'n * p * q = n/4', lo que significa que 2500 en 5 millones es 2 y un poco desviaciones estándar. –

+0

No quise decir [desviación en la forma estadística] (http://en.wikipedia.org/wiki/Deviation_ (estadísticas)) (ya que casi nunca toco el tema y apenas sé algo específico al respecto), pero gracias para el apéndice. – CodeCaster

+0

Ejecuté esto con 500000000 iteraciones, y salió con ~ 0.003% – paul

1

Tenga en cuenta que la diferencia de frecuencia de cada bit varía solo alrededor del 0,08% (-0,03% a + 0,05%). No creo que lo considere significativo. Si cada bit fuera exactamente igualmente probable, encontraría el PRNG muy cuestionable en lugar de cuestionable. Debería esperar algún nivel de varianza en los procesos que se supone que son aleatoriedad de modelado más o menos ...

Cuestiones relacionadas