2012-09-17 34 views
36

Este es mi código para generar números aleatorios utilizando una semilla como argumento.Java Números aleatorios usando una semilla

double randomGenerator(long seed) { 
    Random generator = new Random(seed); 
    double num = generator.nextDouble() * (0.5); 

    return num; 
} 

Cada vez que doy una semilla y trato de generar 100 números, todos son iguales.
Por favor ayuda.

+3

Eso es lo que se supone una semilla que hacer. Usted solo está generando un número para una semilla. ¿Qué estás intentando lograr? –

+0

posible duplicado de [Java aleatorio siempre devuelve el mismo número cuando establezco la semilla?] (Http://stackoverflow.com/questions/5533191/java-random-always-returns-the-same-number-when-i- set-the-seed) – finnw

+2

Puede usar 'System.currentTimeMillis()' como semilla para producir resultados aleatorios. No dar ninguna semilla también produce resultados aleatorios. No estoy seguro de si comenzaría a repetirse en algún momento si no das ninguna semilla. – WVrock

Respuesta

60

Si estás dando la misma semilla, eso es normal, eso es característica importante que permite pruebas.

Comprobar esto para entender la generación de seudo aleatoria y semillas: http://en.wikipedia.org/wiki/Pseudorandom_number_generator

Un generador de números pseudoaleatorios (PRNG), también conocido como un generador de bits aleatorios determinista DRBG, es un algoritmo para generar una secuencia de números que aproxima las propiedades de los números aleatorios. La secuencia no es realmente aleatoria ya que es completamente determinada por un conjunto relativamente pequeño de valores iniciales, llamado estado de PRNG, que incluye una semilla verdaderamente aleatoria.

Si usted quiere tener diferentes secuencias (el caso habitual cuando no sintonizar o para depurar el algoritmo), debe llamar al constructor cero arg que utiliza el nanoTime para tratar de obtener una semilla diferente cada vez. Por supuesto, esta instancia de Random debe mantenerse fuera de su método.

código Probablemente debería ser así:

private Random generator = new Random(); 
double randomGenerator() { 
     return generator.nextDouble()*0.5; 
} 
+0

Millisecond es un tiempo muy largo, sería mucho más seguro tu uso System.nanoTime() – kukis

+0

@kukis No importa. Es solo un número que no es el mismo en cada ** programa ** de lanzamiento. Porque su programa establece la semilla solo una vez. –

+1

usando "new Random()" es equivalente o mejor vea source: public Random() { this (seedUniquifier()^System.nanoTime()); } – dermoritz

6

Ese es el principio de un Pseudo -RNG. Los números no son realmente aleatorios. Se generan usando un algoritmo determinista, pero dependiendo de la semilla, la secuencia de números generados varía. Como siempre usas la misma semilla, siempre obtienes la misma secuencia.

2

El problema es que vuelves a generar el generador aleatorio. Cada vez que lo siembras, el estado inicial del generador de números aleatorios se restablece y el primer número aleatorio que generes será el primer número aleatorio después del estado inicial

6

No debe ser la creación de un nuevo aleatoria en su alcance método. Conviértalo en un miembro de la clase:

public class Foo { 
    private Random random 

    public Foo() { 
     this(System.currentTimeMillis()); 
    } 

    public Foo(long seed) { 
     this.random = new Random(seed); 
    } 

    public synchronized double getNext() { 
     return generator.nextDouble(); 
    } 
} 

Esto es solo un ejemplo. No creo que envolver Random de esta manera agrega ningún valor. Póngalo en una clase suya que lo esté usando.

+0

Lo pongo en mi clase principal y lo llamo desde allí. – WVrock

+0

Esta respuesta casi no está relacionada con la pregunta. –

+3

Puede parecer no relacionado, ya que simplemente parece ser un refactor, pero definitivamente está relacionado. OP volvía a crear instancias del generador aleatorio cada vez que se llamaba al método, por lo que 'nextDouble' siempre devolvería el _primero_ doble en la secuencia aleatoria. Esta respuesta solo crea una instancia del generador aleatorio una vez, y cada vez que se llama 'getNext' realmente pasa por la secuencia aleatoria y devuelve un número diferente cada vez. –

2

Si desea desea generar varios números utilizando una semilla que puede hacer algo como esto:

public double[] GenerateNumbers(long seed, int amount) { 
    double[] randomList = new double[amount]; 
    for (int i=0;i<amount;i++) { 
     Random generator = new Random(seed); 
     randomList[i] = Math.abs((double) (generator.nextLong() % 0.001) * 10000); 
     seed--; 
    } 
    return randomList; 
} 

se mostrará la misma lista si se utiliza la misma semilla.

14

La forma más fácil es usar:

Random rand = new Random(System.currentTimeMillis()); 

Esta es la mejor manera de generar Random números.

0

Varios de los ejemplos aquí crean una nueva instancia de Random, pero esto no es necesario.Tampoco hay ninguna razón para usar synchronized como lo hace una sola solución. En lugar de ello, se aprovechan de los métodos de la clase ThreadLocalRandom:

double randomGenerator() { 
    return ThreadLocalRandom.current().nextDouble(0.5); 
} 
Cuestiones relacionadas