Generar números aleatorios en Java

De ChuWiki
Saltar a: navegación, buscar

Contenido


Para generar números aleatorios en Java tenemos dos opciones. Por un lado podemos usar Math.random(), por otro la clase java.util.Random. La primera es de uso más sencillo y rápido. La segunda nos da más opciones.


Math.random()

La llamada a Math.random() devuelve un número aleatorio entre 0.0 y 1.0, excluido este último valor, es decir, puede devolver 0.346442, 0.2344234, 0.98345,....

En muchas de nuestras aplicaciones no nos servirá este rango de valores. Por ejemplo, si queremos simular una tirada de dado, queremos números entre 1 y 6 sin decimales. Debemos echar unas cuentas para obtener lo deseado.

En primer lugar, miramos cuántos valores queremos. En nuestro caso del dado son 6 valores, del 1 al 6 ambos incluido. Debemos entonces multiplicar Math.random() por 6. Si quisieramos valores entre dos números cualquiera ambos incluídos, por ejemplo, 5 y 10, la cuenta sería (maximo-minimimo)+1, es decir, (10-5)+1 = 6, también multiplicaríamos por 6.

 Math.random()*6   // Esto da valores de 0.0 a 6.0, excluido el 6.0

Como nuestro primer valor es 1, le sumamos 1 al resultado. En el caso de que quisieramos entre 5 y 10, habría que sumar 5, es decir, el valor mínimo.

 Math.random()*6 + 1   // Esto da valores entre 1.0 y 7.0 excluido el 7.0

Finalmente, para conseguir un entero, quitamos los decimales usando la clase Math.floor()

 int valorDado = Math.floor(Math.random()*6+1);

En general, para conseguir un número entero entre M y N con M menor que N y ambos incluídos, debemos usar esta fórmula

  int valorEntero = Math.floor(Math.random()*(N-M+1)+M);  // Valor entre M y N, ambos incluidos.

Si no queremos un valor entero sino double, la fórmula es sin el +1

  double valorAleatorio = Math.random()*(N-M)+M;

eso sí, recuerda que el valor N queda excluido y no saldrá nunca.

Clase java.util.Random

La clase java.util.Random debemos instanciarla, a diferencia del método Math.random(). A cambio, tendremos bastantes más posibilidades.

Podemos usar un constructor sin parámetros o bien pasarle una semilla. Si instanciamos varias veces la clase con la misma semilla, tendremos siempre la misma secuencia de números aleatorios.

Random r1 = new Random();
Random r2 = new Random(4234);
Random r3 = new Random(4234); // r2 y r3 darán la misma secuencia.

Lo más fácil es usar el constructor sin parámetros, que normalmente dará secuencias distintas en cada instancia. De todas formas, una manera de obtener una semilla que sea distinta cada vez que ejecutemos nuestro programa puede ser obtener el tiempo actual en milisegundos con System.currentTimeMillis(), que dará números distintos salvo que hagamos la instacia justo en el mismo instante de tiempo.

Con esta clase, una vez instanciada, nuestro problema del dado sería bastante más sencillo, usando el método nextInt(int n), que devuelve un valor entre 0 y n, excluido n

Random r = new Random();
int valorDado = r.nextInt(6)+1;  // Entre 0 y 5, más 1.

También tenemos funciones que nos dan un valor aleatorio siguiendo una curva de Gauss o que nos rellenan un array de bytes de forma aleatoria. Y por supuesto, el nextDouble() que devuelve un valor aleatorio entre 0.0 y 1.0, excluido este último.