2010-11-23 22 views
13

Sé que si uso el generador aleatorio de Java, generando números con nextInt, los números se distribuirán uniformemente. Pero qué sucede si uso 2 instancias de Aleatorio, generando números con las dos clases aleatorias. Los números serán distribuidos uniformemente o no?Distribución uniforme con Random

Respuesta

7

Los números generados por cada Random ejemplo se distribuirán de manera uniforme, por lo que si se combinan las secuencias de números aleatorios generados por ambos Random casos, deben ser uniformemente distribuidos también.

Tenga en cuenta que incluso si la distribución resultante es uniforme, es posible que desee prestar atención a las semillas para evitar la correlación entre la salida de los dos generadores. Si usa el constructor no-arg predeterminado, las semillas ya deberían ser diferentes. A partir del código fuente de java.util.Random:

private static volatile long seedUniquifier = 8682522807148012L; 

public Random() { this(++seedUniquifier + System.nanoTime()); } 

Si va a configurar la semilla explícitamente (mediante el constructor Random(long seed), o llamando setSeed(long seed)), tendrá que hacerse cargo de esto por sí mismo. Un posible enfoque es usar un generador de números aleatorios para producir las semillas de todos los demás generadores.

+0

excepto ' volátil' no es concesionario para ser atómico. –

+0

@ J-16: Creo que está garantizado con el nuevo modelo de memoria Java presentado con Java 1.5 (http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile) De todos modos, este no es mi código; es la implementación interna de 'java.util.Random'. – Grodriguez

+0

Bajo cualquier JMM, 'long' siempre ha sido atómico independientemente de si lo marca' volátil' o no (lo que significa que nunca verá valores escritos a medias). Lo que no es atómico (de nuevo independientemente de 'volátil') es leer e incrementar y escribir el largo. De modo que es posible que múltiples hilos lean la variable como '0' (por ejemplo), todos incrementen el valor a' 1', y todos vuelvan a escribir '1' en la variable. Para garantizar que el contador se incremente de forma fiable una vez por acceso, necesita sincronización. Las clases en 'java.util.concurrent.atomic' como' AtomicLong' lo hacen fácil y correcto. –

8

Bueno, si se siembran las dos instancias Random con el mismo valor, definitivamente no obtendrá una distribución uniforme discreta de calidad. Consideremos el caso más básico, que literalmente imprime exactamente el mismo número dos veces (no es mucho menos aleatorio que eso ...):

public class RngTest2 { 
    public static void main(String[] args) throws Exception { 
     long currentTime = System.currentTimeMillis(); 
     Random r1 = new Random(currentTime); 
     Random r2 = new Random(currentTime); 
     System.out.println(r1.nextInt()); 
     System.out.println(r2.nextInt()); 
    }   
} 

Pero eso es sólo una única iteración. ¿Qué sucede si comenzamos a subir el tamaño de la muestra?

Aquí es un gráfico de dispersión de una distribución de la ejecución de dos generadores de números aleatorios misma cabeza de serie, de lado a lado para generar 2.000 números suman:

alt text

Y aquí es una distribución de ejecutar un solo RNG para generar números suman 2000:

alt text

parece bastante claro cuál es el enfoque produce más alta calidad de la distribución uniforme discreta sobre este conjunto finito.

Ahora, casi todo el mundo sabe que sembrar dos RNG con la misma semilla es una mala idea si buscas aleatoriedad de alta calidad. Pero este caso hace que se detenga y piense: tenemos creando un escenario donde cada RNG emite de manera independiente aleatoriedad de calidad bastante alta, pero cuando se combina su salida es notablemente inferior en calidad (menos discreto)

+1

Responde una pregunta con una pregunta. –

+0

tiene razón, pero tenga en cuenta que incluso en este caso, la distribución ** resultante es ** uniforme. – Grodriguez

+0

@Grodriguez la trama puede ser engañosa: recuerde que en la primera gráfica de dispersión, cada punto es en realidad 2 puntos que se superponen exactamente. Visualmente, el cuadro 1 parece uniforme solo con menos muestras que el cuadro 2. Pero, de hecho, ambos gráficos tienen el mismo número de muestras, el primero menos aleatorio que el segundo. Al menos, así es como pienso en eso. Me pregunto qué diría la prueba Chi Squared sobre la salida. –

Cuestiones relacionadas