Наскільки випадковий Math.random JavaScript?


116

Протягом 6 років я мав на своєму веб-сайті сторінку генератора випадкових чисел . Тривалий час це був перший або другий результат в Google для "генератора випадкових чисел", і він використовувався для вирішення десятків, якщо не сотень конкурсів та розіграшів на дискусійних форумах і блогах (я знаю, тому що я бачу рефератів у своїх веб-журнали і зазвичай переглядайте).

Сьогодні хтось мені по електронній пошті сказав, що це може бути не так випадково, як я думав. Вона спробувала генерувати дуже великі випадкові числа (наприклад, від 1 до 10000000000000000000) і виявила, що вони майже завжди мають однакову кількість цифр. Дійсно, я завернув цю функцію в циклі, щоб я міг генерувати тисячі чисел і, безумовно, для дуже великих чисел варіація становила лише близько 2 порядків.

Чому?

Ось циклічна версія, тож ви можете спробувати її самі:

http://andrew.hedges.name/experiment/random/randomness.html

Це включає як просту реалізацію, взятою з Мережі розробників Mozilla, так і деякий код від 1997 року, який я видалив з веб-сторінки, яка вже не існує («Central Randomizer 1.3» Пола Хоула). Перегляньте джерело, щоб побачити, як працює кожен метод.

Я читав тут і в інших місцях про Мерсенн Твістер. Мене цікавить те, чому не було б більшої різниці в результатах вбудованої функції Math.random JavaScript . Дякую!


"sarnath'd", як в, побили до удару, або в цьому випадку відповідь
maetl

5
Якщо ви шукаєте відповідь на питання в заголовку, дивіться stackoverflow.com/questions/2344312/…
Ендрю Б.

Відповіді:


182

Дано числа від 1 до 100.

  • 9 мають 1 цифру (1-9)
  • 90 має 2 цифри (10-99)
  • 1 має 3 цифри (100)

Дано числа від 1 до 1000.

  • 9 мають 1 цифру
  • 90 мають 2 цифри
  • 900 мають 3 цифри
  • 1 має 4 цифри

і так далі.

Отже, якщо ви вибираєте кілька випадковим чином, тоді ця переважна більшість вибраних чисел матиме однакову кількість цифр, оскільки переважна більшість можливих значень мають однакову кількість цифр.


11
Ваша ідея випадковості, що ідеально і рівномірно розподілена, інтригує ...

19
@ R.Pate - генерування випадкових чисел не сильно використовує, якщо воно не розподіляється рівномірно у великій масштабі
annakata

3
Прочитайте ще раз. @David лише зазначає, які числа є між межами, а не результат вибору N випадкових чисел. Я визнаю, що титрування вводить в оману.
nikc.org

3
Для запису я проголосував як за це, так і за відповіді @ jwoolard. Я вибрав цю відповідь як прийняту відповідь, оскільки приклади чітко пояснюють, чому розподіл чисел перекошений на числа з більшою кількістю цифр.
Ендрю Хедж

1
@ andrew-hedges цілком правильно - це
чіткіша

56

Ваші результати насправді очікувані. Якщо випадкові числа розподіляються рівномірно в діапазоні від 1 до 10 ^ n, то можна очікувати, що приблизно 9/10 чисел мають n цифр, а ще 9/100 - n-1 цифр.


8
Саме так. Очікується, що розподіл кількості цифр буде скасованим. Однак розподіл журналу кількості цифр повинен бути рівномірним.
Нолдорін

45

Існують різні типи випадковості. Math.random дає рівномірний розподіл чисел.

Якщо ви хочете різних порядків, я б запропонував використовувати експоненціальну функцію для створення того, що називається розподілом закону про владу :

function random_powerlaw(mini, maxi) {
    return Math.ceil(Math.exp(Math.random()*(Math.log(maxi)-Math.log(mini)))*mini)
}

Ця функція повинна дати приблизно однакову кількість одноцифрових чисел, як двоцифрові числа та трицифрові числа.

Існують також інші розподіли за випадковими числами, як звичайний розподіл (також званий Гауссовим розподілом).


За допомогою цього алгоритму я поставив minimum = 1і, maximum = 10і іноді отримав би 11 в результаті. Ви, ймовірно, мали намір використовувати Math.floorзамістьMath.round
Сем Етон

1
Чому це працює? Чи перетворює це рівномірний розподіл на експоненціальний розподіл?
shinzou

@shinzou Я запитав у math.stackexchange і отримав дещо іншу формулу як відповідь. Я змінив код, щоб відобразити математично отриману формулу з math.stackexchange.
Крістіан

20

Мені виглядає абсолютно випадково! (Підказка: Це залежить від браузера.)

Особисто я думаю, що моя реалізація була б кращою, хоча я вкрав її від XKCD , хто ВЖЕ завжди повинен бути визнаний:

function random() {
  return 4; // Chosen by a fair dice throw. Guaranteed to be random.
}

19
+1 для згадки про його залежність від браузера, -1 для запозичення xkcd без посилання.

Потрібно чи ні, оскільки це xkcd, його приписують. :)
Arafangion

2
ОТ: Я здивований і щасливий, що на цьому тижні "XKCD" відповів на питання університетських викликів: D
Метт Сах

2
Бергі: Прямого посилання недостатньо?
Арафангіон

Я думаю, що вони означають, що жарт не цитується правильно ("випадковий = 4;" замість "повернути 4;")
Ерен Тантекін

18

У наступному документі пояснюється, наскільки math.random () у основних веб-браузерах (не) безпечний: "Тимчасове відстеження користувачів у основних браузерах та витоки та атаки міждоменної інформації" від Amid Klein (2008) . Це не сильніше, ніж типові функції Java або Windows, вбудовані в PRNG.

З іншого боку, реалізація SFMT періоду 2 ^ 19937-1 вимагає 2496 байт внутрішнього стану, що підтримується для кожної послідовності PRNG. Деякі люди можуть вважати це невиправданою вартістю.


1
+1: Згаданий документ чудовий, набагато вищий за рамки початкового питання.
Roland Illig

6

Якщо ви використовуєте таке число, як 10000000000000000000, ви виходите за точність типу даних, який використовує Javascript. Зауважте, що всі створені числа закінчуються на "00".


1
Однак це не його проблема.
Joey

3
@Johannes - це одна з його проблем :)
annakata

Поширення IEE754 не рівномірне. Можливо, ви можете представляти від 0 до 999 з кроком у два і маєте для цього достатньо точності, тому ви помітите рівномірний розподіл у цьому діапазоні, якщо ви вибираєте число багато разів. 10% буде двозначним, а 90% - тризначним. Якщо ви почнете вражати дійсно високі цифри, приріст перевищить 1. Ви можете лише перейти від трильйона до трильйона мільярдів, а не трильйона мільярдів і одного. Хоча для невеликої кількості / масштабів, цей ефект буде незначним до неіснуючого. Ефект масштабу матиме набагато більший вплив.
jgmjgm

5

Я спробував генератор псевдовипадкових чисел JS в грі Chaos .

Мій трикутник Сьєрпіньського говорить, що це досить випадково: Фрактал


2
Чи не заперечуєте ви поділитися кодом трикутника тут та jsfiddle / jsbin, щоб ми могли легко перевірити його на практиці для різних браузерів?
Фабріціо Матте

1
Гаразд, але дайте мені кілька днів, бо мені потрібно перекласти код англійською мовою. Зараз це польсько-англійська мова, і у мене багато роботи.
zie1ony

1
@ zie1ony пара днів.
trusktr

1
УСП :( робота, робота, робота Посилання: kubaplas.vot.pl/green/fractal Перший параметр NR з вершини Другий є точкою перетину (від 0 до 1) від відрізка Просто експеримент ...
zie1ony

4
Посилання мертвих - можливо, замість цього Gpotub репо?
Марк К Коуан

3

Ну, якщо ви генеруєте числа до, скажімо, 1e6, ви, сподіваємось, отримаєте всі числа з приблизно однаковою ймовірністю. Це також означає, що у вас є лише один десятий шанс отримати число на одну цифру менше. Шанс на отримання сто цифр менше, і т. Д. Я сумніваюся, що ви побачите велику різницю при використанні іншого RNG, оскільки у вас рівномірний розподіл по числах, а не їх логарифм.


0

Невипадкові числа, рівномірно розподілені від 1 до N, мають однакову властивість. Зауважте, що (в деякому сенсі) це питання точності. Рівномірний розподіл на 0-99 (як цілі числа) має 90% його чисел, які мають дві цифри. Рівномірний розподіл на 0-999999 має 905 його номерів, які мають п'ять цифр.

Будь-який набір чисел (за деяких не надто обмежувальних умов) має щільність. Коли хтось хоче обговорити "випадкові" числа, слід вказати щільність цих чисел (як зазначено вище). Загальною щільністю є рівномірна щільність. Є й інші: експоненціальна щільність, нормальна щільність і т. Д. Потрібно вибрати, яка щільність є актуальною, перш ніж запропонувати генератор випадкових чисел. Крім того, числа, що надходять з однієї щільності, часто можна легко перетворити на іншу щільність за допомогою кар'єрних засобів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.