Hay dos problemas que causan lo que ves. El primero es que el código establece un valor inicial para una instancia Aleatoria. El segundo es que el método instancia "aleatorio" instancia un nuevo objeto aleatorio y luego establece inmediatamente su semilla con la misma semilla cada vez. La combinación de estas dos garantías de que, por el mismo valor de i, el método "aleatorio" siempre devolverá el mismo valor y siempre será el primero en la secuencia que la semilla siempre genera.
Asumiendo que la configuración de la semilla es obligatoria, para obtener el siguiente valor en la secuencia en lugar del mismo primer valor de la secuencia cada vez, la instancia randnum de Random no puede establecerse cada vez antes de su siguiente método se llama. Para solucionarlo, mueva la instancia de randnum local variable de Random desde el alcance del método de instancia aleatorio al ámbito de clase. En segundo lugar, establezca la semilla solo cuando se le asigne una instancia Aleatoria aleatoria o solo para obtener la misma secuencia de resultados para volver a comenzar. El método de instancia setSeed (semilla larga) de Class Random no se puede ejecutar en el alcance de la clase, por lo que el constructor tiene que establecerlo usando el constructor Random con el parámetro seed largo. El siguiente código muestra los cambios:
public class RandomDemo { // arbitrary example class name
// lots of class related stuff may be here...
// still inside the class scope...
// private is a good idea unless an external method needs to change it
private Random randnum = new Random(123456789L);
// the seed guarantees it will always produce the same sequence
// of pseudo-random values when the next methods get called
// for unpredicable sequences, use the following constructor instead:
// private Random randnum = new Random();
// lots of code may be here...
// publicly exposed instance method for getting random number
// from a sequence determined by seed 123456789L
// in the range from 0 through i-1
public int randnum(int i) {
// don't set the seed in here, or randnum will return the exact same integer
// for the same value of i on every method call
// nextInt(i) will give the next value from randnum conforming to range i
return randnum.nextInt(i);
} // end randnum
// lots of more code may be here...
} // end class RandDemo
Lo anterior le dará una solución exacta a su problema exacto, como se indica. Sin embargo, usar una semilla obligatoria parece inusual, dado lo que hace.
Si esto es para un proyecto de clase o una prueba de software donde la secuencia tiene que ser predecible y repetible, tiene sentido establecer la semilla en un valor fijo. De lo contrario, cuestione la validez de establecer la semilla en algún valor predeterminado. A continuación, se explica más acerca de Random, semillas para Random y por qué hay una disposición para el suministro de una semilla.
Random tiene dos constructores:
Random()
y
Random(long seed)
y un método de instancia
setSeed(long seed)
que todos afectan la secuencia de números obtenidos a partir de una instancia aleatoria. El método de instancia,
setSeed(long seed)
establece el objeto aleatorio al mismo estado que habría sido en si se hubiera simplemente ejemplificada con la misma simiente como el argumento del constructor. Solo se utilizan los 48 bits de bajo orden de un valor inicial.
Si un objeto Random se instancia sin una semilla, la semilla será la misma que la hora del sistema en milisegundos. Esto garantiza que, a menos que se realicen instancias de dos objetos aleatorios en el mismo milisegundo, producirán diferentes secuencias pseudoaleatorias. Solo se usan los 48 bits de menor valor de la semilla. Esto causa secuencias pseudoaleatorias impredecibles. No es necesario y es un desperdicio de recursos de computación obtener una nueva instancia de Aleatorio cada vez que uno llama al siguiente método.
Los parámetros de inicialización de Random se proporcionan para que uno pueda instanciar un objeto aleatorio que produzca una secuencia repetible. Para una semilla dada, se garantiza que la secuencia de valores en los siguientes métodos será la misma secuencia siempre que se use esa semilla.Esto es útil para probar software que utilizará secuencias pseudoaleatorias donde los resultados deben ser predecibles y repetibles. No es útil para crear diferentes secuencias pseudoaleatorias impredecibles en funcionamiento.
La afirmación "es obligatorio que establezca la semilla" niega cualquier imprevisibilidad de las secuencias pseudoaleatorias del objeto Random. ¿Esto es para un proyecto de clase o prueba de software donde los resultados tienen que ser los mismos para las mismas entradas al programa?
No cree un nuevo objeto aleatorio cada vez que llame a la función. Guárdelo como una variable privada y ejemplínelo solo una vez – Rob
¿A qué le está asignando la semilla? –
No se recomienda configurar manualmente la semilla a menos que sepa exactamente lo que significa. – m0skit0