1. Numerele pseudo-aleatorie
Uneori, un programator se confruntă cu sarcini aparent simple: „selectează un film aleatoriu dintr-o anumită listă”, „alege un câștigător la loterie”, „se amestecă lista de redare când utilizatorul își scutură smartphone-ul”, „alege un număr aleatoriu pentru a cripta un mesaj” , etc. În fiecare caz, dezvoltatorul pune o întrebare logică: cum să obțineți un număr aleatoriu?
De fapt, obținerea unui număr cu adevărat aleatoriu este destul de dificil de făcut. De fapt, este atât de dificil încât în unele computere sunt încorporate coprocesoare matematice speciale pentru a genera numere care să îndeplinească toate cerințele pentru adevărata aleatorie.
Programatorii au venit cu propria lor soluție: numere pseudoaleatoare . Numerele pseudo-aleatorie sunt un fel de succesiune, ale cărei numere par a fi aleatoare. Cu toate acestea, efectuând o analiză atentă, un expert poate găsi anumite modele în secvență. Astfel de numere nu sunt potrivite pentru criptarea documentelor secrete, dar sunt suficiente pentru a simula aruncarea unui zar într-un joc.
Există mulți algoritmi pentru generarea unei secvențe de numere pseudoaleatoare. Aproape toate generează următorul număr aleatoriu pe baza numărului anterior și a unor numere auxiliare suplimentare.
De exemplu, acest program va afișa 1000
numere care nu se repetă:
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());
}
}
}
Apropo, aici nu vorbim de numere pseudoaleatoare. Vorbim despre o succesiune de numere pseudoaleatoare. Privind un singur număr, este imposibil să spunem dacă este aleatoriu sau nu.
Într-adevăr, există mai multe moduri de a obține un număr aleatoriu:
public static int getRandomNumber()
{
return 4; // Here's a random number (we got it by rolling a die)
}
2.Math.random()
În Java, Math
clasa are o metodă specială care returnează un număr aleator. Și după cum ați putea ghici, metoda se numește random
. În general, iată cum arată să numim această metodă:
Math.random()
Această metodă nu ia parametri și returnează un număr real pseudoaleator în intervalul de la 0
până la 1
. Numărul 1 în sine nu este inclus în interval.
Exemplu:
Cod | Ieșire de consolă |
---|---|
|
|
Dar dacă această metodă nu este exact ceea ce aveți nevoie? Să presupunem că doriți să scrieți un program care simulează lansarea unui zar cu șase fețe. Cum obții numere întregi aleatorii în intervalul 1..6, în loc de numere reale din intervalul 0..1?
De fapt, este destul de simplu.
În primul rând, trebuie să mapați intervalul [0, 1)
pe [0, 6)
. Pentru a face acest lucru, pur și simplu înmulțiți rezultatul returnat random()
cu 6
. Desigur, pentru a obține numere întregi, trebuie să rotunjiți:
Cod | Ieșire de consolă |
---|---|
|
|
Returnează getRandomDieNumber()
un număr întreg aleatoriu în interval 0..5
inclusiv. Dar nu va fi un număr în set 1, 2, 3, 4, 5, 6
. Va fi un număr din set 0, 1, 2, 3, 4, 5
.
Dacă ceea ce aveți nevoie sunt numerele din set 1, 2, 3, 4, 5, 6
, adăugați doar unul la numerele aleatorii:
Cod | Ieșire de consolă |
---|---|
|
|
Acum e perfect!
3. Random
clasa
Java are o clasă specială Random
care încapsulează o secvență de numere pseudoaleatoare. Puteți crea mai multe obiecte ale Random
clasei. Fiecare dintre aceste obiecte va genera propria sa secvență de numere pseudoaleatoare.
Aceasta este o clasă super interesantă, cu o mulțime de metode interesante. Să începem cu cel mai simplu.
double nextDouble()
Această metodă returnează un număr real aleatoriu în intervalul 0.0
- 1.0
. Este foarte asemănător cu Math.random()
metoda. Și nu e de mirare, deoarece Math.random()
metoda apelează pur și simplu nextDouble()
metoda pe un Random
obiect.
float nextFloat()
Această metodă este foarte asemănătoare cu nextDouble()
metoda, dar numărul aleator returnat este un float
. De asemenea, se află în intervalul 0.0
- 1.0
. Și, ca întotdeauna în Java, intervalul nu include numărul 1.0
în sine.
Random r = new Random();
float f = r.nextFloat();
int nextInt(int max)
Această metodă returnează un număr întreg aleatoriu în intervalul [0, max)
. 0
este inclus în gamă, dar max
nu este.
Cu alte cuvinte, dacă doriți să obțineți un număr aleator în set 1, 2, 3, 4, 5, 6
, atunci trebuie să adăugați unul la numărul aleator returnat:
Random r = new Random();
int x = r.nextInt(6) + 1;
int nextInt()
Această metodă este similară cu cea anterioară, dar nu ia niciun parametru. Deci, care este intervalul pentru valorile sale returnate? De la -2 billion
până la +2 billion
.
Ei bine, mai precis, de la -2147483648
până la +2147483647
.
long nextLong()
Această metodă este similară cu nextInt()
metoda, dar valoarea returnată va cădea undeva în întregul interval posibil de long
s.
boolean nextBoolean()
Această metodă returnează o boolean
valoare aleatorie: false
sau true
. Acest lucru este foarte convenabil atunci când trebuie să obțineți o secvență lungă de valori booleene aleatoare.
void nextBytes(byte[] data)
Această metodă nu returnează nimic (deoarece tipul de returnare este void
). În schimb, umple matricea transmisă cu valori aleatorii. Acest lucru este foarte util atunci când aveți nevoie de un buffer mare plin cu date aleatorii.
double nextGaussian()
Această metodă returnează un număr real aleatoriu în intervalul 0.0
- 1.0
. Cu toate acestea, numerele nu sunt distribuite uniform în acest interval. În schimb, ele urmează o distribuție normală .
Valorile aproape de mijlocul intervalului ( 0.5
) vor apărea mai des decât valorile de la sfârșitul intervalului.
În cazul nostru, vârful distribuției valorii va fi la0.5