1. Псевдовипадкові числа
Іноді програміст стикається з нібито простими завданнями: «добрати випадковий фільм для вечірнього перегляду з певного списку», «обрати переможця лотереї», «перемішати список пісень під час струшування смартфона», «вибрати випадкове число для шифрування повідомлення», і щоразу в нього виникає цілком закономірне питання: а як отримати отаке випадкове число?
Взагалі, якщо вам потрібно отримати «справжнє випадкове число», зробити це досить-таки важко. Справа доходить до того, що в комп'ютер вбудовують спеціальні математичні співпроцесори, які вміють генерувати такі числа з дотриманням усіх вимог до «справжньої випадковості».
Тому програмісти придумали власне рішення — псевдовипадкові числа. Псевдовипадкові числа — це деяка послідовність, в якій числа на перший погляд здаються випадковими, але фахівець, виконавши докладний аналіз, зможе знайти в них певні закономірності. Для шифрування секретних документів такі числа не підійдуть, а от для імітації кидання кубика в грі — цілковито.
Є багато алгоритмів генерування послідовності псевдовипадкових чисел, і майже всі вони генерують наступне випадкове число на основі попереднього та ще деяких допоміжних чисел.
Наприклад, ця програма виведе на екран 1000
неповторюваних чисел:
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());
}
}
}
До речі, ми говоримо не про окремі псевдовипадкові числа, а саме про послідовність таких чисел, оскільки дивлячись на одне число, неможливо зрозуміти, випадкове воно чи ні.
Адже випадкове число можна отримати різними способами:
public static int getRandomNumber()
{
return 4; // це точно випадкове число (викинули його на кубиках)
}
2. Метод Math.random()
Клас Math
у Java має спеціальний метод, який повертає випадкове число. І як ви вже, можливо, здогадуєтеся, цей метод має назву random
. Його виклик має такий загальний вигляд:
Math.random()
Метод не отримує жодного параметра, але повертає результат — псевдовипадкове дійсне число в діапазоні від 0
до 1
. Одиниця до діапазону не входить.
Приклад:
Код | Виведення на екран |
---|---|
|
|
А що робити, якщо вам цей метод не дуже підходить, а ви хочете, припустімо, написати програму, яка імітує кидання кубика з шістьма гранями? Як отримати випадкові цілі числа в діапазоні 1…6, а не дійсні в діапазоні 0…1?
Насправді це досить просто.
Спочатку треба перетворити діапазон [0,1)
на [0, 6)
. Для цього просто слід помножити результат функції random()
на 6
. Ну а щоб отримати цілі числа, потрібно це все округлити:
Код | Виведення на екран |
---|---|
|
|
Функція getRandomDiceNumber()
повертає випадкове ціле число з діапазону 0…5
включно. Тільки це будуть числа не з набору 1,2,3,4,5,6
, а з набору 0,1,2,3,4,5
.
Якщо потрібні числа саме з набору 1,2,3,4,5,6
, слід просто до всіх випадкових чисел додавати одиницю:
Код | Виведення на екран |
---|---|
|
|
Отепер ідеально!
3. Клас Random
У Java є спеціальний клас Random
, який інкапсулює послідовність псевдовипадкових чисел. Можна створити кілька об'єктів класу Random
, і кожен із цих об'єктів генеруватиме свою послідовність псевдовипадкових чисел.
Це дуже цікавий клас, і він має багато цікавих методів. Почнімо з найпростіших:
Метод double nextDouble()
Цей метод повертає випадкове дійсне число в діапазоні 0.0
–1.0
. Дуже схоже на метод Math.random()
. І нічого дивного, адже метод Math.random()
просто викликає метод nextDouble()
для об'єкта типу Random
.
Метод float nextFloat()
Метод дуже схожий на метод nextDouble()
, тільки повертає він випадкове число типу float
. Воно також лежить в діапазоні 0.0
–1.0
. І, як завжди, у Java діапазон не включає число 1.0
.
Random r = new Random();
float f = r.nextFloat();
Метод int nextInt(int max)
Цей метод повертає випадкове ціле число в діапазоні [0, max)
. 0
входить до діапазону, max
— не входить.
Тобто якщо ви хочете отримати випадкове число з набору 1, 2, 3, 4, 5, 6
, вам доведеться додати до отриманого випадкового числа одиницю:
Random r = new Random();
int x = r.nextInt(6) + 1;
Метод int nextInt()
Цей метод подібний до попереднього, але не отримує жодного параметра. Тоді в якому ж діапазоні він генерує числа? Від -2 мільярдів
до +2 мільярдів
.
Точніше від -2147483648
до +2147483647
.
Метод long nextLong()
Цей метод подібний до методу nextInt()
, тільки повертатиме він значення з усього можливого діапазону значень типу long
.
Метод boolean nextBoolean()
Цей метод повертає випадкове значення типу boolean
: false
або true
. Дуже зручно, якщо потрібно отримати довгу послідовність випадкових логічних значень.
Метод void nextBytes(byte[] data)
Цей метод не повертає нічого (тип void
). Натомість він заповнює переданий у нього масив випадковими значеннями. Дуже зручно, якщо потрібен великий буфер, заповнений випадковими даними.
Метод double nextGaussian()
Цей метод повертає випадкове дійсне число в діапазоні 0.0
–1.0
. От тільки числа в цьому діапазоні розподілені не рівномірно, а підпорядковані нормальному розподілу.
Числа, ближчі до середини діапазону (0.5
), випадатимуть частіше, ніж значення по краях діапазону.
Пік значень у нашому випадку припаде на 0.5
.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ