1. Números pseudoaleatorios
A veces, un programador se enfrenta a tareas aparentemente sencillas: "seleccionar una película aleatoria de una lista determinada", "elegir un ganador de la lotería", "reproducir aleatoriamente la lista de reproducción cuando el usuario agita su teléfono inteligente", "elegir un número aleatorio para cifrar un mensaje". , etc. En cada caso, el desarrollador hace una pregunta lógica: ¿cómo obtener un número aleatorio?
En realidad, obtener un número verdaderamente aleatorio es bastante difícil de hacer. De hecho, es tan difícil que se incorporan coprocesadores matemáticos especiales en algunas computadoras para generar números que satisfagan todos los requisitos para una verdadera aleatoriedad.
A los programadores se les ocurrió su propia solución: números pseudoaleatorios . Los números pseudoaleatorios son un tipo de secuencia, cuyos números parecen ser aleatorios. Sin embargo, al realizar un análisis cuidadoso, un experto puede encontrar ciertos patrones en la secuencia. Dichos números no son adecuados para cifrar documentos secretos, pero son suficientes para simular el lanzamiento de un dado en un juego.
Hay muchos algoritmos para generar una secuencia de números pseudoaleatorios. Casi todos generan el siguiente número aleatorio en función del número anterior y algunos números auxiliares adicionales.
Por ejemplo, este programa mostrará 1000
números que no se repiten:
public class Main
{
public static int a = 41;
public static int c = 11119;
public static int m = 11113;
public static int seed = 1;
public static int getNextRandom()
{
seed = (a * seed + c) % m;
return seed;
}
public static void main(String[] args)
{
for (int i = 0; i < 1000; i++)
{
System.out.println(getNextRandom());
}
}
}
Por cierto, aquí no estamos hablando de números pseudoaleatorios. Estamos hablando de una secuencia de números pseudoaleatorios. Mirando un solo número, es imposible saber si es aleatorio o no.
De hecho, hay varias formas de obtener un número aleatorio:
public static int getRandomNumber()
{
return 4; // Here's a random number (we got it by rolling a die)
}
2.Math.random()
En Java, la Math
clase tiene un método especial que devuelve un número aleatorio. Y como puede suponer, el método se llama random
. En general, esto es lo que parece llamar a este método:
Math.random()
Este método no toma parámetros y devuelve un número real pseudoaleatorio en el rango de 0
a 1
. El número 1 en sí no está incluido en el rango.
Ejemplo:
Código | Salida de consola |
---|---|
|
|
Pero, ¿y si este método no es exactamente lo que necesita? Suponga que desea escribir un programa que simule lanzar un dado de seis caras. ¿Cómo obtienes números enteros aleatorios en el rango 1..6, en lugar de números reales en el rango 0..1?
En realidad es bastante simple.
Primero, debe mapear el rango [0, 1)
en [0, 6)
. Para hacer esto, simplemente multiplique el resultado devuelto random()
por 6
. Por supuesto, para obtener números enteros, debe redondear:
Código | Salida de consola |
---|---|
|
|
devuelve getRandomDieNumber()
un entero aleatorio en el rango 0..5
inclusive. Pero no será un número en el conjunto 1, 2, 3, 4, 5, 6
. Será un número en el conjunto 0, 1, 2, 3, 4, 5
.
Si lo que necesita son números en el conjunto 1, 2, 3, 4, 5, 6
, simplemente agregue uno a los números aleatorios:
Código | Salida de consola |
---|---|
|
|
¡Eso es perfecto!
3. Random
clase
Java tiene una Random
clase especial que encapsula una secuencia de números pseudoaleatorios. Puede crear varios objetos de la Random
clase. Cada uno de estos objetos generará su propia secuencia de números pseudoaleatorios.
Esta es una clase súper interesante con muchos métodos interesantes. Empecemos por lo más sencillo.
double nextDouble()
Este método devuelve un número real aleatorio en el rango 0.0
- 1.0
. Es muy similar al Math.random()
método. Y no es de extrañar, ya que el Math.random()
método simplemente llama al nextDouble()
método en un Random
objeto.
float nextFloat()
Este método es muy similar al nextDouble()
método, pero el número aleatorio devuelto es un float
. También se encuentra en el rango 0.0
- 1.0
. Y, como siempre en Java, el rango no incluye el número 1.0
en sí.
Random r = new Random();
float f = r.nextFloat();
int nextInt(int max)
Este método devuelve un número entero aleatorio en el rango [0, max)
. 0
está incluido en la gama, pero max
no lo está.
En otras palabras, si desea obtener un número aleatorio en el conjunto 1, 2, 3, 4, 5, 6
, debe agregar uno al número aleatorio devuelto:
Random r = new Random();
int x = r.nextInt(6) + 1;
int nextInt()
Este método es similar al anterior, pero no toma ningún parámetro. Entonces, ¿cuál es el rango de sus valores de retorno? De -2 billion
a +2 billion
.
Bueno, para ser precisos, de -2147483648
a +2147483647
.
long nextLong()
Este método es similar al nextInt()
método, pero el valor devuelto caerá en algún lugar del rango posible completo de long
s.
boolean nextBoolean()
Este método devuelve un boolean
valor aleatorio: false
o true
. Esto es muy conveniente cuando necesita obtener una secuencia larga de valores booleanos aleatorios.
void nextBytes(byte[] data)
Este método no devuelve nada (ya que el tipo de retorno es void
). En cambio, llena la matriz pasada con valores aleatorios. Esto es muy útil cuando necesita un gran búfer lleno de datos aleatorios.
double nextGaussian()
Este método devuelve un número real aleatorio en el rango 0.0
- 1.0
. Sin embargo, los números no están distribuidos uniformemente en este rango. En cambio, siguen una distribución normal .
Los valores cerca de la mitad del rango ( 0.5
) ocurrirán con más frecuencia que los valores en los extremos del rango.
En nuestro caso, el pico de la distribución de valor estará en0.5
GO TO FULL VERSION