2011-10-26 14 views
17

Quiero generar números aleatorios en Java, sé que debo usar métodos existentes como Math.random(), sin embargo, mi pregunta es: ¿cómo puedo generar la misma secuencia de números, cada vez que ejecuto mi aplicación? ejemplo: la secuencia generada es: 0,9, 0.08,0.6 por lo que quiero que esta secuencia se genera cada vez que ejecuto este método ..Generación de la misma secuencia de números aleatorios

Respuesta

29

Claro - acaba de crear una instancia de Random en lugar de utilizar Math.random(), y siempre especifique la misma semilla:

Random random = new Random(10000); // Or whatever seed - maybe configurable 
int diceRoll = random.nextInt(6) + 1; // etc 

Tenga en cuenta que se vuelve más difícil si su aplicación tiene múltiples hilos involucrados, ya que el tiempo se vuelve menos predecible.

Esto toma ventaja de Random siendo pseudo-random number generator - en otras palabras, cada vez que le pide un nuevo resultado, manipula el estado interno para darle una secuencia de aspecto aleatorio, pero conociendo la semilla (o de hecho la corriente interna estado) es completamente predecible.

+2

En el caso de los hilos, podría dar a cada hilo su propio azar (con semilla fija) o si usa solo unos pocos números una lista pre poblada para cada uno de un azar (con semilla fija). Sin embargo, si los hilos interactúan entre sí, este enfoque ya no funcionará tampoco. – Stefan

6

Debe inicializar el generador de números aleatorios.

Random random = new Random(aFixedNumber); 
random.nextInt(); // will always be the same 
24

Un ejemplo del uso repetido de la misma semilla.

public static void main(String... args) throws IOException { 
    printDoublesForSeed(1); 
    printDoublesForSeed(128); 
    printDoublesForSeed(1); 
    printDoublesForSeed(128); 
} 

private static void printDoublesForSeed(long seed) { 
    double[] doubles = new double[10]; 
    Random rand = new Random(seed); 
    for (int j = 0; j < doubles.length; j++) { 
     doubles[j] = (long) (rand.nextDouble() * 100)/100.0; 
    } 
    System.out.println("doubles with seed " + seed + " " + Arrays.toString(doubles)); 
} 

impresiones

doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93] 
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47] 
doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93] 
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47] 

editar un abuso interesante de semillas aleatorias.

public static void main(String ... args) { 
    System.out.println(randomString(-6225973)+' '+randomString(1598025)); 
} 

public static String randomString(int seed) { 
    Random rand = new Random(seed); 
    StringBuilder sb = new StringBuilder(); 
    for(int i=0;i<5;i++) 
     sb.append((char) ('a' + rand.nextInt(26))); 
    return sb.toString(); 
} 

impresiones

hello world 
+2

+1 Para una ilustración clara. – mre

+2

Me gusta el ejemplo de Hello World. Supongo que no hay mejor solución que aplicar fuerza bruta a todas las semillas posibles para encontrar las correctas. Edit: Doh obviamente no, no debería escribir cosas antes de tomar mi primer café: o – Voo

+0

Acabo de utilizar la fuerza bruta. ;) –

4

Math.random es sólo un envoltorio de la clase java.util.Random. La primera vez que llame al Math.random se crea una instancia de la clase java.util.Random.

Ahora, la mayoría de las API no exponen ningún verdadero generadores de números aleatorios, porque no se pueden implementar en el software. En su lugar, usan generadores de números pseudoaleatorios, que generan una secuencia de números de aspecto aleatorio usando un conjunto de fórmulas. Esto es lo que hace java.util.Random. Sin embargo, cada generador de números pseudoaleatorios debe ser primero sembrado. Si tiene dos generadores de números pseudoaleatorios que usan el mismo algoritmo y usan la misma semilla, producirán el mismo resultado.

Por defecto, java.util.Random usa los milisegundos desde el 1 de enero de 1970 como semilla. Por lo tanto, cada vez que inicie su programa, producirá diferentes números (a menos que lo administre para comenzar java en menos de 1 milisegundo). Por lo tanto, la solución a su problema es crear su propia java.util.Random instancia y sembrarla en solitario:

import java.util.Random; 

class ... { 
    Random randomNumberGenerator = new Random(199711); 

    public void ...() 
    { 
     int randomInt = randomNumberGenerator.nextInt(); 
     double randomDouble = randomNumberGenerator.nextDouble(); 
    } 
} 

El randomNumberGenerator siempre habrá escupir la misma secuencia de números, siempre y cuando no cambie la semilla (el 199711).

0

Me gustaría codificar los números en la aplicación. Esto requiere más memoria, pero es mucho más rápido.

Simplemente imprima números aleatorios en el terminal, luego cópielos y péguelos en su código.

Asegúrese de dejar un comentario explicando lo que ha hecho, o se verán como magia negra para el lector desinformado.

Cuestiones relacionadas