2012-04-01 22 views
11

Tengo un gran programa distribuido en muchos servidores físicos diferentes, cada programa genera muchos hilos, cada subproceso usa Math.random() en sus operaciones para dibujar una pieza de muchos grupos de recursos comunes.cómo aleatorio es Math.random() en java a través de diferentes jvms o máquinas diferentes

El objetivo es utilizar las agrupaciones de manera uniforme en todas las operaciones. A veces, no parece tan aleatorio al mirar una instantánea en un grupo de recursos para ver qué piezas está obteniendo en ese instante (en realidad podría ser, pero es difícil de medir y averiguar con certeza).

¿Hay algo mejor que Math.random() y funciona igual de bien (al menos no peor)?

+0

+1 para una buena pregunta. Por favor, hágamelo saber si encuentra una respuesta :) –

+0

Por favor, eche un vistazo al siguiente enlace. http: //www.coderanch.com/t/510167/java/java/Error generador aleatorio –

+0

¿Por qué no utilizar algunos programadores para los grupos de recursos comunes? –

Respuesta

2

Math.random() se basa en java.util.Random, que se basa en linear congruential generator. Eso significa que su aleatoriedad no es perfecta, pero es lo suficientemente buena para la mayoría de las tareas, y parece que debería ser suficiente para su tarea.

Sin embargo, parece que está utilizando el valor de retorno double de Math.random() para elegir entre un número fijo de opciones, lo que puede degradar aún más la calidad de la aleatoriedad. Sería mejor usar java.util.Random.nextInt() - solo asegúrese de reutilizar el mismo objeto Random.

A veces, no parece tan aleatorio examinado una instantánea en un fondo de recursos para ver qué piezas se está haciendo en ese instante

Nuestros cerebros son muy buenos para reconocer patrones en perfecta aleatoriedad , entonces eso significa casi nada.

+0

buen punto en Random.nextInt(), actualmente simplemente multiplico el doble aleatorio por n y luego lo redondeo al entero más cercano, ¿es eso muy diferente de Random(). NextInt()? – user881480

+0

@ user881480: yes - Random produce enteros, Math.random() hace un trabajo extra para convertir eso a un doble, solo para que lo convierta nuevamente en un int. Esta doble conversión podría reducir la calidad de la aleatoriedad (no muy cierta, pero podría ser). –

0

Este hilo puede ser útil: How good is java.util.Random?

otras alternativas:

  • generar una semilla aleatoria cuando init la instancia aleatoria
  • si el uso de usar Linux/dev/urandom
+0

No deseo llamar al proceso externo desde Java ya que degrada el rendimiento, estoy ejecutando a una velocidad de 1 operación por segundo y hay muchos (cientos de miles o millones) por día en un servidor. – user881480

+0

por lo que lo más fácil que puedo pensar es crear su propio generador con un período más largo (como se describe en el enlace). también debe recordar que la posibilidad de obtener 1,1,1,1,1 es la misma posibilidad que 45,1002,783,199,6 – shem

1

El algoritmo de Math.Random es "lo suficientemente aleatorio" para cualquier plataforma. El modelo matemático utilizado para crear números aleatorios psuedo es bueno. Depende de cuántos hilos uses. Para cualquier cosa que no sea una gran cantidad de subprocesos, esto no le dará una distribución uniforme (la naturaleza de los números aleatorios), y luego Math.random() le dará un montón de sobrecarga.

Pruebe una mejor opción: cree una clase de grupo de recursos, que los distribuye de manera uniforme, y luego simplemente mantenga su sección crítica protegida en el método de "distribución".

+0

¿por qué los números al azar no le darían una distribución pareja? en mi caso, el número de subprocesos por programa es de unos pocos cientos, pero cada subproceso realiza muchas operaciones (1 por segundo, donde cada operación llama a Math.random()). – user881480

+0

¿cómo distribuiría una clase de grupo de recursos los recursos aleatoriamente? ¿tiene que usar Math.random()? – user881480

+0

No necesita distribuirlo aleatoriamente, simplemente cree una clase simple llamada Resources, un método nextResource() sincronizado. De esta forma, sigue repasando uno a uno, asegurando una distribución pareja. Además, usar cientos de subprocesos crea más sobrecarga que el tiempo ahorrado excepto en algunos casos muy específicos; debe limitar la cantidad de subprocesos a lo que su sistema puede usar de manera eficiente. – user1304831

0

Según el javadoc Math.random() es solo una manera fácil de usar java.util.Random. Dicho esto, es solo un algoritmo pseudoaleatorio. Una manera fácil de comprobar qué tan aleatorio es realmente un algoritmo es dibujar puntos aleatorios en la cuadrícula x/y. No deberías encontrar ningún patrón.

Para obtener números reales de ramdom, puede usar servicios como http://www.random.org. Si esto se ralentiza, tal vez lo llame regularmente para sembrar java.util.Random podría acercarlo al verdadero azar.

+0

¿cómo obtiene el nuevo java.util.Random() una semilla distinta? – user881480

Cuestiones relacionadas