Math.random()
Содержание:
- Что такое генераторы псевдослучайных чисел?
- Generate random numbers between range
- Using Random class
- Usage
- Using ThreadLocalRandom class
- How Math.random() is implemented
- What is Randomness in Javascript?
- Git Essentials
- Math и метод random
- История двух генераторов
- Генерирование целочисленных псевдослучайных значений
Что такое генераторы псевдослучайных чисел?
Эта иллюстрация поясняет мысль фон Неймана: очевидно, что сгенерированная последовательность чисел не является случайной. Для многих задач этого вполне достаточно. Но нам нужен алгоритм, генерирующий числа, которые кажутся случайными. Технически они должны казаться независимыми и одинаково распределёнными случайными переменными, равномерно распределёнными по всему диапазону генератора. Другими словами, нам нужно безопасно притвориться, что наши псевдослучайные числа являются истинно случайными.
Если результат работы генератора очень трудно отличить от истинно случайной последовательности, то его называют высококачественным генератором. В противном случае — низкокачественным. По большей части качество определяется эмпирически, путём прогона статистических тестов на уровень случайности. Например, оценивается количество нулей и единиц, вычисляется число коллизий, применяется метод Монте-Карло для вычисления π и т. д. Другой, более прагматичный метод оценки качества PRNG заключается в анализе его работы на практике и сравнении с истинно случайными числами.
Помимо неслучайности результата, рассматриваемый нами простой алгоритм демонстрирует и другие важные особенности, свойственные всем PRNG. Если долго генерировать числа, то рано или поздно начнёт повторяться одна и та же последовательность. Это свойство называется периодичностью, и ею «страдают» все PRNG.
Период, или длина цикла, — это длина последовательности чисел, создаваемых генератором до первого повторения.
Можно рассматривать PRNG как сильно сжатую шифровальную книгу, содержащую последовательность чисел. Какой-нибудь шпион мог бы использовать его в качестве одноразового блокнота. Начальной позицией в этой «книге» является seed(). Постепенно вы дойдёте до её конца и вернётесь к началу, завершив цикл.
Большая длина цикла не гарантирует высокое качество, но весьма ему способствует. Часто он гарантируется каким-то математическим доказательством. Даже когда мы не можем точно вычислить длину цикла, нам вполне по силам определить его верхнюю границу. Поскольку следующее состояние PRNG и его результат являются детерминистическими функциями текущего состояния, то длина цикла не может быть больше количества возможных состояний. Для достижения максимальной длины генератор должен пройти через все возможные состояния, прежде чем вернуться в текущее.
Если состояние PRNG описывается как k-бит, то длина цикла ≤ 2k. Если она действительно достигает этого значения, то такой генератор называют генератором полного цикла. В хороших PRNG длина цикла близка к этой верхней границе. В противном случае вы будете зря тратить память.
Давайте теперь проанализируем количество уникальных случайных значений, генерируемых PRNG с помощью некой детерминистической трансформации выходных данных. Допустим, нам надо сгенерировать три случайных числа от 0 до 15, вроде 2, 13, 4 или 5, 12, 15. У нас может быть 163 = 4096 таких тройных комбинаций, но рассматриваемый нами простой генератор может выдать лишь 16 комбинаций:
Так мы приходим к ещё одному свойству всех PRNG: количество уникальных значений, которые могут быть сгенерированы из псевдослучайной последовательности, ограничивается длиной цикла последовательности.
Неважно, какие значения мы генерируем в данном случае. Их может быть 16 комбинаций из четырёх значений (или любой другой длины), 16 уникальных матричных массивов и т
д. Не более 16 уникальных значений любого типа.
Вспомните наш алгоритм для генерирования случайных идентификаторов, состоящих из 22 символов, берущихся из 64-символьного словаря. Получается, что мы генерируем комбинации из 22 чисел от 0 до 63. И здесь мы сталкиваемся с той же проблемой: количество возможных уникальных идентификаторов ограничено размером внутреннего состояния PRNG и длиной его цикла.
Generate random numbers between range
If you want to generate random numbers between certain range, you can use Random and ThreadLocalRandom to do it.
1 |
packageorg.arpit.java2blog; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; publicclassGenerateRandomInRangeMain{ publicstaticvoidmain(Stringargs){ intminimum=10; intmaximum=20; System.out.println(«============================»); System.out.println(«Generating 5 random integer in range of 10 to 20 using Random»); System.out.println(«============================»); Random randomGenerator=newRandom(); for(inti=;i<5;i++){ System.out.println(randomGenerator.nextInt((maximum-minimum)+1)+minimum); } System.out.println(«============================»); System.out.println(«Generating 5 random integer in range of 10 to 20 using ThreadLocalRandom»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(ThreadLocalRandom.current().nextInt(minimum,maximum+1)); } System.out.println(«============================»); System.out.println(«Generating 5 random integer in range of 10 to 20 using Math.random»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(minimum+(int)(Math.random()*((maximum-minimum)+1))); } } } |
Output:
============================
Generating 5 random integer in range of 10 to 20 using Random
============================
11
18
14
13
15
============================
Generating 5 random integer in range of 10 to 20 using ThreadLocalRandom
============================
10
12
13
13
16
============================
Generating 5 random integer in range of 10 to 20 using Math.random
============================
14
10
16
20
15
That’s all about generating random numbers in java.
Using Random class
You can use java.util.Random to generate random numbers in java.You can generate integers, float, double, boolean etc using Random class.
Let’s understand with the help of example:
1 |
packageorg.arpit.java2blog; import java.util.Random; publicclassRandomClassGeneratorMain{ publicstaticvoidmain(Stringargs){ Random randomGenerator=newRandom(); System.out.println(«============================»); System.out.println(«Generating 5 random integers»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(randomGenerator.nextInt()); } System.out.println(«============================»); System.out.println(«Generating 5 random double»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(randomGenerator.nextDouble()); } System.out.println(«============================»); System.out.println(«Generating 5 random floats»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(randomGenerator.nextFloat()); } System.out.println(«============================»); System.out.println(«Generating 5 random booleans»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(randomGenerator.nextBoolean()); } } } |
Output:
============================
Generating 5 random integers
============================
1342618771
-1849662552
1719085329
2141641685
-819134727
============================
Generating 5 random doubles
============================
0.1825454639005325
0.5331492085899436
0.830900901839756
0.8490109501015005
0.7968080535091425
============================
Generating 5 random floats
============================
0.9831014
0.24019146
0.11383718
0.42760438
0.019532561
============================
Generating 5 random booleans
============================
false
false
true
true
false
Usage
In your project, run the following command:
npm install random-js
or
yarn add random-js
In your code:
import{Random}from"random-js";constrandom=newRandom();constvalue=random.integer(1,100);
const{Random}=require("random-js");constrandom=newRandom();constvalue=random.integer(1,100);
Or to have more control:
constRandom=require("random-js").Random;constrandom=newRandom(MersenneTwister19937.autoSeed());constvalue=random.integer(1,100);
It is recommended to create one shared engine and/or instance per-process rather than one per file.
Download and place it in your project, then use one of the following patterns:
define(function(require){var Random =require("random");returnnewRandom.Random(Random.MersenneTwister19937.autoSeed());});define(function(require){var Random =require("random");returnnewRandom.Random();});define("random",function(Random){returnnewRandom.Random(Random.MersenneTwister19937.autoSeed());});
Download and place it in your project, then add it as a tag as such:
<scriptsrc="lib/random-js.min.js"><script><script>var random =newRandom.Random();alert("Random value from 1 to 100: "+random.integer(1,100));</script>
Using ThreadLocalRandom class
You can use ThreadLocalRandom class to generate random numbers.This class got introduced in Java 7.Although java.util.Random is thread safe but multiple threads tries to access same object, there will be lot of contention and performance issue.In case of ThreadLocalRandom, each thread will generate their own random numbers and there won’t be any contention.
Let’s understand with the help of example:
1 |
packageorg.arpit.java2blog; import java.util.concurrent.ThreadLocalRandom; publicclassThreadLocalRandomMain{ publicstaticvoidmain(Stringargs){ System.out.println(«============================»); System.out.println(«Generating 5 random integers»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(ThreadLocalRandom.current().nextInt()); } System.out.println(«============================»); System.out.println(«Generating 5 random doubles»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(ThreadLocalRandom.current().nextDouble()); } System.out.println(«============================»); System.out.println(«Generating 5 random floats»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(ThreadLocalRandom.current().nextFloat()); } System.out.println(«============================»); System.out.println(«Generating 5 random booleans»); System.out.println(«============================»); for(inti=;i<5;i++){ System.out.println(ThreadLocalRandom.current().nextBoolean()); } } } |
Output:
============================
Generating 5 random integers
============================
-315342453
-1922639586
-19084346
-615337866
-1075097641
============================
Generating 5 random doubles
============================
0.9074981945011997
0.7626761438609163
0.4439078754038527
0.8663565773294881
0.8133933685024771
============================
Generating 5 random floats
============================
0.50696343
0.4109127
0.4284398
0.37340754
0.28446126
============================
Generating 5 random booleans
============================
false
true
false
false
true
How Math.random() is implemented
The Math.random() method internally creating a single new pseudorandom-number generator, exactly as if by the expression new java.util.Random(). This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else. The nextDouble() method of Random class is called on this pseudorandom-number generator object.
This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.
As the largest double value less than 1.0 is Math.nextDown(1.0), a value x in the closed range where x1<=x2 may be defined by the statements.
If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or you find anything incorrect? Let us know in the comments. Thank you!
❮ Math.round()
Java Tutorial ❯
What is Randomness in Javascript?
It is impossible in computing to generate completely random numbers. This is because every calculation inside a computer has a logical basis of cause and effect, while random events don’t follow that logic.
Computers are not capable of creating something truly random. True randomness is only possible through a source of external data that a computer cannot generate, such as the movement of many lava lamps at once (which has been used as an unbreakable random encryption in the real world), meteographic noise, or nuclear decay.
The solution that Javascript, and other programming languages, use to implement randomness is “pseudo-random” number generation. Javascript random numbers start from a hidden internal value called a “seed.” The seed is a starting point for a hidden sequence of numbers that are uniformly distributed throughout their possible range.
Developers cannot change Javascript’s pseudo-random seed or the distribution of values in its generated pseudo-random sequences. Different Javascript implementations and different browsers often start with different seeds. Do not assume that different browsers, or even different computers, will always use the same seed.
Javascript random numbers are not safe for use in cryptography because deciphering the seed could lead to decryption of the hidden number sequence. Some functions exist to create cryptographically secure pseudo-random numbers in Javascript, but they are not supported by older browsers.
In this blog post, we’ll first cover the canonical methods of creating Javascript random numbers. Then we’ll move onto ways of obtaining higher-quality random data; your needs will determine the worthwhile effort.
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
95
И если вы хотите генерировать последовательности, можно создать вспомогательный метод:
public static List intsInRange(int size, int lowerBound, int upperBound) { SecureRandom random = new SecureRandom(); List result = new ArrayList<>(); for (int i = 0; i < size; i++) { result.add(random.nextInt(upperBound - lowerBound) + lowerBound); } return result; }
Которые вы можете использовать в качестве:
List integerList = intsInRange3(5, 0, 10); System.out.println(integerList);
И что приводит к:
Математика.случайная()
Класс предоставляет нам отличные вспомогательные методы, связанные с математикой. Одним из них является метод , который возвращает случайное значение в диапазоне . Как правило, он используется для генерации случайных значений процентиля.
Тем не менее, аналогично взлом – вы можете использовать эту функцию для генерации любого целого числа в определенном диапазоне:
int min = 10; int max = 100; int randomNumber = (int)(Math.random() * (max + 1 - min) + min); System.out.println(randomNumber);
Хотя этот подход еще менее интуитивен, чем предыдущий. Выполнение этого кода приводит к чему-то вроде:
43
Если вы хотите работать с последовательностью, мы создадим вспомогательный метод для добавления каждого сгенерированного значения в список:
public static List intsInRange(int size, int lowerBound, int upperBound) { List result = new ArrayList<>(); for (int i = 0; i < size; i++) { result.add((int)(Math.random() * (upperBound + 1 - lowerBound) + lowerBound)); } return result; }
И тогда мы можем назвать это так:
List integerList = intsInRange(5, 0, 10); System.out.println(integerList);
Который производит:
ThreadLocalRandom.nextInt()
Если вы работаете в многопоточной среде, класс предназначен для использования в качестве потокобезопасного эквивалента . К счастью, он предлагает метод nextInt () как верхней, так и нижней границей:
int randomInt = ThreadLocalRandom.current().nextInt(0, 10); System.out.println(randomInt);
Как обычно, нижняя граница включена, в то время как верхняя граница отсутствует:
3
Аналогично, вы можете создать вспомогательную функцию для создания последовательности этих:
public static List intsInRange(int size, int lowerBound, int upperBound) { List result = new ArrayList<>(); for (int i = 0; i < size; i++) { result.add(ThreadLocalRandom.current().nextInt(lowerBound, upperBound)); } return result; }
Которые вы можете использовать в качестве:
List integerList = intsInRange4(5, 0, 10); System.out.println(integerList);
SplittableRandom.ints()
Менее известным классом в Java API является класс , который используется в качестве генератора псевдослучайных значений. Как следует из названия, он разбивается и работает параллельно, и на самом деле используется только тогда, когда у вас есть задачи, которые можно снова разделить на более мелкие подзадачи.
Стоит отметить, что этот класс также основан на небезопасной генерации семян-если вы ищете безопасную генерацию семян, используйте .
Класс предлагает метод , который, с нашей точки зрения, работает так же, как :
List intList = new SplittableRandom().ints(5, 1, 11) .boxed() .collect(Collectors.toList()); System.out.println(intList);
Что приводит к:
И, если вы хотите сгенерировать только одно случайное число, вы можете отказаться от коллектора и использовать с :
int randomInt = new SplittableRandom().ints(1, 1, 11).findFirst().getAsInt(); System.out.println(randomInt);
Что приводит к:
4
Вывод
В этом уроке мы подробно рассмотрели как генерировать случайные целые числа в диапазоне в Java .
Мы рассмотрели новейший и наиболее полезный метод, а также некоторые другие популярные методы выполнения этой задачи. Большинство подходов основаны на или эквивалентных классах, используемых для более конкретных контекстов.
Math и метод random
Вроде бы всё просто, вызвал свойство у объекта и вот тебе числа. Но не всё так просто, это конечно не чистый природный рандом а эмулятор, псевдо-рандом. Но и он поможет написать вам интересную программу, например русское лото.
Но генерирует он числа от 0 до 1, так что разберём нюансы написания скрипта и вызова random, так же наполним массив случайными числами.
JavaScript
<script>
var rand = Math.random(); //Но минус в том что генерирует он от нуля до единицы
document.write(rand);
document.write(«<br /><hr />»);
var rand2 = Math.random() * 100; //Так мы получим случайное число в диапазоне от 0 до 100
document.write(rand2);
document.write(«<br /><hr />»);
var rand3 = Math.round(Math.random() * 100); //Наконец то нормальное человеческое число))
document.write(rand3);
document.write(«<br /><hr />»);
//Теперь нам надо задать диапазон в котором числа будут рандомизировать, здесь вам пришлось бы повозиться если бы всё ещё до вас не придумали
function myRandom(from, to){
return Math.floor((Math.random() * (to — from + 1)) + from); //Тут уже нужны математические мозги
}
document.write(myRandom(50,60));
/**********************************************************************************************************************/
//Заполняем массив рандомными числами
var randArr = new Array(10);
var start = 40;
var fin = 80;
function myRandom2(from, to){
return Math.floor((Math.random() * (to — from + 1)) + from); //Тут уже нужны математические мозги
}
function randomArray(arr,begin,end){
for(var i = 0; i < arr.length; i++){
arr = myRandom2(begin,end); //Так просто 0_о!!! В смысле я думал понадобиться метод типа push
document.write(arr + «<br />»);
}
}
document.write(«<br /><hr />Значения в массиве формируются от » + start + » и до » + fin + «<br />»);
randomArray(randArr,start,fin); //Можно спрограммировать игру «русское лото» какие числа будут выпадать
</script>
1 |
<script> varrand=Math.random();//Но минус в том что генерирует он от нуля до единицы document.write(rand); document.write(«<br /><hr />»); varrand2=Math.random()*100;//Так мы получим случайное число в диапазоне от 0 до 100 document.write(rand2); document.write(«<br /><hr />»); varrand3=Math.round(Math.random()*100);//Наконец то нормальное человеческое число)) document.write(rand3); document.write(«<br /><hr />»); //Теперь нам надо задать диапазон в котором числа будут рандомизировать, здесь вам пришлось бы повозиться если бы всё ещё до вас не придумали functionmyRandom(from,to){ returnMath.floor((Math.random()*(to-from+1))+from);//Тут уже нужны математические мозги } document.write(myRandom(50,60)); varrandArr=newArray(10); varstart=40; varfin=80; functionmyRandom2(from,to){ returnMath.floor((Math.random()*(to-from+1))+from);//Тут уже нужны математические мозги } functionrandomArray(arr,begin,end){ for(vari=;i<arr.length;i++){ arri=myRandom2(begin,end);//Так просто 0_о!!! В смысле я думал понадобиться метод типа push document.write(arri+»<br />»); } } document.write(«<br /><hr />Значения в массиве формируются от «+start+» и до «+fin+»<br />»); randomArray(randArr,start,fin);//Можно спрограммировать игру «русское лото» какие числа будут выпадать </script> |
Количество просмотров: 415
| Категория: JavaScript | Тэги: JavaScript / random / основы / числа
История двух генераторов
Давайте ещё раз посмотрим на код генерирования идентификаторов:
Замечаете, в чём проблема? Два генератора довольно странно миксуются в алгоритме V8. Числа из двух потоков не объединяются по модулю 2 (xor). Вместо этого просто конкатенируются нижние 16 бит выходных данных каждого подгенератора. Похоже, проблема именно в этом. Когда мы умножим Math.random() на 64 и приведём к наименьшему (floor), то у нас останутся верхние 6 битов. Эти биты генерируются исключительно одним из двух MWC-подгенераторов.
Красным выделены биты от PRNG № 1, синим — от PRNG № 2.
Но будь это так, мы почти сразу же начали бы замечать коллизии. Но мы их не замечали. Чтобы понять, почему этого не происходило, давайте вспомним пример с генерированием комбинаций из трёх чисел средствами 4-битного LCG.
В данном случае парадокс дней рождений неприменим — последовательность даже близко нельзя назвать случайной, так что мы не можем притвориться. Очевидно, что до 17-й комбинации дублей не будет. То же самое происходит и с PRNG в V8: при определённых условиях недостаток случайности снижает вероятность того, что мы увидим коллизию.
То есть детерминированность генератора сыграла нам на руку. Но так бывает не всегда. Главный вывод, который мы сделали, заключается в том, что даже в высококачественном PRNG нельзя предполагать случайность распределения, если длина цикла не будет гораздо больше, чем количество генерируемых вами значений.
В случаях, подобных нашему, когда пытаются генерировать уникальные значения с помощью нескольких независимых последовательностей от одного генератора, беспокоятся не столько о случайности, сколько о том, чтобы последовательности не совпадали. Допустим, у нас есть N последовательностей с длиной L от генератора с периодом P. Тогда вероятность совпадения будет равна
Короче, если вы используете Math.random() в V8 и вам нужна достаточно качественная последовательность случайных чисел, то не используйте более 24 тыс. чисел. А если генерируете в несколько мощных потоков и вам нужно избегать совпадений, то вообще забудьте о Math.random().
Генерирование целочисленных псевдослучайных значений
Для генерирования целочисленных псевдослучайных значений используется представленное выше выражение, в котором
произведение «приводится» к целочисленному значению. Например, попробуем получить псевдослучайное значение в диапазоне
Обратите внимание, что закрывающаяся скобка квадратная, т.е. 20 входит в диапазон
В этом случае к разности
между максимальным и минимальным значениями следует добавить 1, т.е. определить диапазон целочисленных значений [5,21),
где 21 не попадает в желаемый диапазон :
// после подстановки значений int i = (int)Math.random() * (20 - 5 + 1) + 5; // получаем int i = (int)Math.random() * 16 + 5;