1. Numeri pseudocasuali
A volte un programmatore deve affrontare compiti apparentemente semplici: "selezionare un film a caso da un determinato elenco", "scegliere un vincitore della lotteria", "mescolare la playlist quando l'utente scuote lo smartphone", "scegliere un numero a caso per crittografare un messaggio" , ecc. In ogni caso, lo sviluppatore pone una domanda logica: come ottenere un numero casuale?
In realtà, ottenere un numero veramente casuale è piuttosto difficile. In effetti, è così difficile che speciali coprocessori matematici siano incorporati in alcuni computer per generare numeri che soddisfino tutti i requisiti per una vera casualità.
I programmatori hanno trovato la loro soluzione: i numeri pseudocasuali . I numeri pseudocasuali sono un tipo di sequenza i cui numeri sembrano essere casuali. Tuttavia, eseguendo un'attenta analisi, un esperto può trovare determinati schemi nella sequenza. Tali numeri non sono adatti per cifrare documenti segreti, ma sono sufficienti per simulare il lancio di un dado in un gioco.
Esistono molti algoritmi per generare una sequenza di numeri pseudocasuali. Quasi tutti generano il numero casuale successivo in base al numero precedente e alcuni numeri ausiliari aggiuntivi.
Ad esempio, questo programma visualizzerà 1000
numeri non ripetitivi:
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());
}
}
}
A proposito, qui non stiamo parlando di numeri pseudocasuali. Stiamo parlando di una sequenza di numeri pseudocasuali. Guardando un singolo numero, è impossibile dire se sia casuale o meno.
In effetti, ci sono vari modi per ottenere un numero casuale:
public static int getRandomNumber()
{
return 4; // Here's a random number (we got it by rolling a die)
}
2.Math.random()
In Java, la Math
classe ha un metodo speciale che restituisce un numero casuale. E come puoi immaginare, il metodo si chiama random
. In generale, ecco come sembra chiamare questo metodo:
Math.random()
Questo metodo non accetta parametri e restituisce un numero reale pseudocasuale nell'intervallo da 0
a 1
. Il numero 1 stesso non è incluso nell'intervallo.
Esempio:
Codice | Uscita console |
---|---|
|
|
Ma cosa succede se questo metodo non è proprio quello di cui hai bisogno? Supponiamo di voler scrivere un programma che simuli il lancio di un dado a sei facce. Come si ottengono numeri interi casuali nell'intervallo 1..6, invece di numeri reali nell'intervallo 0..1?
In realtà è piuttosto semplice.
Innanzitutto, devi mappare l'intervallo [0, 1)
su [0, 6)
. Per farlo basta moltiplicare il risultato restituito da random()
per 6
. Naturalmente, per ottenere numeri interi, è necessario arrotondare:
Codice | Uscita console |
---|---|
|
|
Il getRandomDieNumber()
restituisce un numero intero casuale nell'intervallo 0..5
compreso. Ma non sarà un numero nel set 1, 2, 3, 4, 5, 6
. Sarà un numero nel set 0, 1, 2, 3, 4, 5
.
Se ciò di cui hai bisogno sono i numeri nel set 1, 2, 3, 4, 5, 6
, aggiungine uno ai numeri casuali:
Codice | Uscita console |
---|---|
|
|
Adesso è perfetto!
3. Random
classe
Java ha una Random
classe speciale che incapsula una sequenza di numeri pseudocasuali. È possibile creare diversi oggetti della Random
classe. Ciascuno di questi oggetti genererà la propria sequenza di numeri pseudocasuali.
Questa è una classe super interessante con molti metodi interessanti. Iniziamo con il più semplice.
double nextDouble()
Questo metodo restituisce un numero reale casuale nell'intervallo 0.0
- 1.0
. È molto simile al Math.random()
metodo. E non c'è da stupirsi, dal momento che il Math.random()
metodo chiama semplicemente il nextDouble()
metodo su un Random
oggetto.
float nextFloat()
Questo metodo è molto simile al nextDouble()
metodo, ma il numero casuale restituito è un float
. Si trova anche nella gamma 0.0
- 1.0
. E, come sempre in Java, l'intervallo non include il numero 1.0
stesso.
Random r = new Random();
float f = r.nextFloat();
int nextInt(int max)
Questo metodo restituisce un numero intero casuale nell'intervallo [0, max)
. 0
è incluso nella gamma, ma max
non lo è.
In altre parole, se vuoi ottenere un numero casuale nel set 1, 2, 3, 4, 5, 6
, devi aggiungerne uno al numero casuale restituito:
Random r = new Random();
int x = r.nextInt(6) + 1;
int nextInt()
Questo metodo è simile al precedente, ma non richiede alcun parametro. Quindi qual è l'intervallo per i suoi valori di ritorno? Da -2 billion
a +2 billion
.
Beh, per essere precisi, da -2147483648
a +2147483647
.
long nextLong()
Questo metodo è simile al nextInt()
metodo, ma il valore restituito cadrà da qualche parte nell'intero intervallo possibile di long
s.
boolean nextBoolean()
Questo metodo restituisce un boolean
valore casuale: false
o true
. Questo è molto utile quando è necessario ottenere una lunga sequenza di valori booleani casuali.
void nextBytes(byte[] data)
Questo metodo non restituisce nulla (poiché il tipo restituito è void
). Invece, riempie l'array passato con valori casuali. Questo è molto utile quando hai bisogno di un grande buffer pieno di dati casuali.
double nextGaussian()
Questo metodo restituisce un numero reale casuale nell'intervallo 0.0
- 1.0
. Tuttavia, i numeri non sono distribuiti uniformemente in questo intervallo. Invece, seguono una distribuzione normale .
I valori vicini al centro dell'intervallo ( 0.5
) si verificano più spesso dei valori alle estremità dell'intervallo.
Nel nostro caso, il picco della distribuzione del valore sarà a0.5
GO TO FULL VERSION