НИИ МЛЯ
(прокрастинация. профанация. прострация.)
На главную Отдел ИИ Отдел ПА Отдел РП Лаборатория ЕН Лаборатория ЭХ
Лаборатория естественных наук

О мультипликативных датчиках случайных чисел

(Принято к публикации 2015-07-16)

Как известно, мультипликативный датчик случайных чисел может быть записан в следующем виде:

Sn = (A × Sn-1 + C) mod M
Rn = (Sn + 1) / (M + 1)
Здесь {Rn} - последовательность псевдослучайных чисел из интервала (0, 1). Нетрудно заметить, что этот алгоритм зависит от некоторых констант A, C, M и от начального элемента вспомогательной целочисленной последовательности S0. Насколько удачные числа мы возьмём, настолько сильнее последовательность {Rn} будет похожа на случайную.

Пусть у нас, например, есть такие значения:

A C M S0
Попробуем определиться, какие критерии для выяснения "случайности" последовательности, полученной применением этих значений, мы можем использовать.

Перво-наперво, сгенерируем несколько псевдослучайных чисел:

Длина последовательности:

Теперь можно оценить, насколько наша последовательность хорошо симулирует равномерность случайных чисел на отрезке (0, 1):
или, если её элементы сгруппировать попарно и рассматривать эти пары как координаты точек плоскости, насколько равномерно она заполняет единичный квадрат:
Можно даже построить весёленькую столбчатую диаграмму, иллюстрирующую процентное соотношение точек, попавших в ту или иную область единичного отрезка:

Однако достаточно ли этих картинок, чтобы утверждать "равномерность" нашей последовательности? Рассмотрим такой график:

Здесь по оси ординат отложены номера элементов последовательности, а по оси абсцисс - их значения. На первый взгляд всё хорошо, но давайте попробуем поставить такие значения:

Как видим, несмотря на кажущуюся равномерность разброса точек на первых рисунках, последний график демонстрирует некий регулярный орнамент.

Разумеется, мультипликативные датчики являются не единственным способом получить последовательность псевдослучайных чисел. Например, для этой цели можно использовать метод срединных квадратов. Суть его состоит в следующем:

  1. Выбирается некое начальное число S0. Например, S0=12345.
  2. Это число представляется в двоичном виде, S0=00110000001110012.
  3. Вычисляется квадрат числа: (S0)2=000010010001010101101100101100012.
  4. Из этого квадрата выбирается середина: 00001001 ( 0001010101101100 ) 101100012 и объявляется новым элементом последовательности: S1=00010101011011002=5484.
Конечно, этот датчик несовершенен. Например, если начальный элемент равен нулю, то все остальные окажутся тоже нулевыми. Тем не менее, для такого датчика наши вышеприведенные тесты тоже подходят:

Наконец, посмотрим, как все вышеприведенные картинки будут выглядеть с использованием датчика псевдослучайных чисел, встроенного в Javascript: