Линейный конгруэнтный генератор ( LCG ) — это алгоритм , который генерирует последовательность псевдослучайных чисел, рассчитанную с помощью разрывного кусочно-линейного уравнения . Метод представляет собой один из старейших и наиболее известных алгоритмов генератора псевдослучайных чисел . Теорию, лежащую в их основе, относительно легко понять, и они легко и быстро реализуются, особенно на компьютерном оборудовании, которое может обеспечить модульную арифметику путем усечения битов памяти.
Генератор определяется рекуррентным соотношением :
где – последовательность псевдослучайных значений, а
— целочисленные константы, определяющие генератор. Если c = 0, генератор часто называют мультипликативным конгруэнтным генератором (MCG) или ГСЧ Лемера . Если c ≠ 0, метод называется смешанным конгруэнтным генератором . [1] : 4-
Когда c ≠ 0, математик назвал бы повторение аффинным преобразованием , а не линейным , но это неправильное название хорошо укоренилось в информатике. [2] : 1
Генератор Лемера был опубликован в 1951 году [3] , а линейный конгруэнтный генератор был опубликован в 1958 году У. Э. Томсоном и А. Ротенбергом. [4] [5]
Преимущество LCG заключается в том, что правильный выбор параметров приводит к тому, что период становится известным и продолжительным. Хотя это и не единственный критерий, слишком короткий период является фатальной ошибкой генератора псевдослучайных чисел. [6]
Хотя LCG способны генерировать псевдослучайные числа , которые могут пройти формальные тесты на случайность , качество вывода чрезвычайно чувствительно к выбору параметров m и a . [7] [1] [8] [9] [10] [2] Например, a = 1 и c = 1 дают простой счетчик по модулю , который имеет длинный период, но явно неслучайен.
Исторически неудачный выбор приводил к неэффективному внедрению LCG. Особенно наглядным примером этого является RANDU , который широко использовался в начале 1970-х годов и привел ко многим результатам, которые в настоящее время подвергаются сомнению из-за использования этого плохого LCG. [11]
Существует три распространенных семейства параметров выбора:
Это оригинальная конструкция Lehmer RNG. Период равен m −1, если множитель a выбран примитивным элементом целых чисел по модулю m . Начальное состояние должно быть выбрано между 1 и m −1.
Одним из недостатков простого модуля является то, что модульное приведение требует произведения двойной ширины и явного шага приведения. Часто используется простое число, меньшее степени 2 ( популярны простые числа Мерсенна 2 31 −1 и 2 61 −1), так что приведение по модулю m = 2 e − d можно вычислить как ( ax mod 2 e ) + d ⌊ топор /2 е ⌋ . За этим должно следовать условное вычитание m , если результат слишком велик, но количество вычитаний ограничено ad / m , которое можно легко ограничить одним, если d мало.
Если произведение двойной ширины недоступно и множитель выбран тщательно, можно использовать метод Шраге [12] . Для этого множим m = qa + r , т.е. q = ⌊ m / a ⌋ и r = m mod a . Затем вычислите ax mod m знак равно a ( x mod q ) − r ⌊ x / q ⌋ . Поскольку x mod q < q ≤ m / a , первый член строго меньше am / a = m . Если a выбрано так, что r ≤ q (и, следовательно, r / q ≤ 1), то второй член также меньше m : r ⌊ x / q ⌋ ≤ rx / q = x ( r / q ) ≤ x < m . Таким образом, оба произведения могут быть вычислены с помощью произведения одинарной ширины, а разница между ними лежит в диапазоне [1− m , m −1], поэтому может быть уменьшена до [0, m −1] с помощью одного условного сложения. . [13]
Второй недостаток заключается в том, что сложно преобразовать значение 1 ≤ x < m в однородные случайные биты. Если используется простое число, меньшее степени 2, иногда недостающие значения просто игнорируются.
Выбор m в качестве степени 2 , чаще всего m = 2 32 или m = 2 64 , дает особенно эффективный LCG, поскольку это позволяет вычислять операцию модуля путем простого усечения двоичного представления. Фактически, старшие биты обычно вообще не вычисляются. Однако есть и недостатки.
Эта форма имеет максимальный период m /4, достигаемый, если a ≡ ±3 (mod 8) и начальное состояние X 0 нечетно. Даже в этом лучшем случае три младших бита X чередуются между двумя значениями и, таким образом, вносят в состояние только один бит. X всегда нечетно (младший бит никогда не меняется), и только один из следующих двух бит всегда изменяется. Если a ≡ +3, X чередуется ±1↔±3, а если a ≡ −3, X чередуется ±1↔∓3 (все по модулю 8).
Можно показать, что эта форма эквивалентна генератору с модулем m /4 и c ≠ 0. [1]
Более серьезная проблема с использованием модуля степени двойки заключается в том, что младшие биты имеют более короткий период, чем старшие биты. Его простота реализации обусловлена тем фактом, что на биты никогда не влияют биты более высокого порядка, поэтому младшие биты такого генератора сами по себе образуют LCG по модулю 2 b , повторяясь с периодом 2 b -2 . Только самый старший бит X достигает полного периода.
Когда c ≠ 0, правильно выбранные параметры допускают период, равный m , для всех начальных значений. Это произойдет тогда и только тогда, когда : [1] : 17—19.
Эти три требования называются теоремой Халла – Добелла. [14] [15]
Эту форму можно использовать с любым m , но хорошо работает только для m со многими повторяющимися простыми множителями, например степенью 2; использование размера слова компьютера является наиболее распространенным выбором. Если бы m было целым числом без квадратов , это допускало бы только a ≡ 1 (mod m ), что делает ГПСЧ очень плохим; выбор возможных множителей полного периода доступен только в том случае, если m имеет повторяющиеся простые множители.
Хотя теорема Халла – Добелла обеспечивает максимальный период, этого недостаточно, чтобы гарантировать хороший генератор. Например, желательно, чтобы a - 1 не делилось на простые множители m больше , чем это необходимо. Таким образом, если m — степень 2, то a − 1 должно делиться на 4, но не делиться на 8, т. е. a ≡ 5 (по модулю 8). [1] : §3.2.1.3
Действительно, большинство множителей создают последовательность, которая не проходит тот или иной тест на неслучайность, и найти множитель, который удовлетворяет всем применимым критериям [1] : §3.3.3 , довольно сложно. Спектральный тест является одним из наиболее важных тестов. [16]
Обратите внимание, что модуль степени 2 разделяет проблему, описанную выше для c = 0: младшие k бит образуют генератор с модулем 2 k и, таким образом, повторяются с периодом 2 k ; только самый старший бит достигает полного периода. Если требуется псевдослучайное число меньше r , ⌊ rX / m ⌋ является результатом гораздо более высокого качества, чем X mod r . К сожалению, большинство языков программирования значительно упрощают написание последнего ( X % r
), поэтому это более распространенная форма.
Генератор не чувствителен к выбору c , если он относительно прост по модулю (например, если m — степень 2, то c должно быть нечетным), поэтому обычно выбирается значение c =1.
Ряд, полученный при другом выборе c, можно записать как простую функцию ряда, когда c =1. [1] : 11 В частности, если Y является прототипическим рядом, определяемым Y 0 = 0 и Y n +1 = aY n +1 mod m, то можно записать общий ряд X n +1 = aX n + c mod m. как аффинная функция Y :
В более общем смысле любые две серии X и Z с одинаковым множителем и модулем связаны соотношением
В следующей таблице перечислены широко используемые параметры LCG, включая встроенные функции rand() в библиотеках времени выполнения различных компиляторов . Эта таблица призвана продемонстрировать популярность, а не примеры для подражания; многие из этих параметров плохие. Доступны таблицы хороших параметров. [10] [2]
Как показано выше, LCG не всегда используют все биты в создаваемых ими значениях. Обычно они возвращают наиболее значимые биты. Например, реализация Java на каждой итерации оперирует 48-битными значениями, но возвращает только 32 старших бита. Это связано с тем, что биты старшего порядка имеют более длинные периоды, чем биты младшего порядка (см. ниже). LCG, использующие этот метод усечения, дают статистически лучшие значения, чем те, которые этого не делают. Это особенно заметно в скриптах, использующих операцию модификации для уменьшения дальности; изменение мода 2 случайного числа приведет к чередованию 0 и 1 без усечения.
Напротив, некоторые библиотеки используют неявный модуль степени двойки, но никогда не выводят или иным образом не используют самый старший бит, чтобы ограничить вывод положительными целыми числами с дополнением до двух . Вывод такой , как если бы модуль был на один бит меньше внутреннего размера слова, и такие генераторы описаны как таковые в таблице выше.
LCG работают быстро и требуют минимального объема памяти (один модуль , часто 32 или 64 бита) для сохранения состояния. Это делает их ценными для моделирования нескольких независимых потоков. LCG не предназначены и не должны использоваться для криптографических приложений; для таких приложений используйте криптографически безопасный генератор псевдослучайных чисел .
Хотя у LCG есть несколько конкретных недостатков, многие из их недостатков связаны со слишком маленьким государством. Тот факт, что люди в течение стольких лет убаюкивали их использование с такими малыми модулями, можно рассматривать как свидетельство силы этой техники. LCG с достаточно большим состоянием может пройти даже строгие статистические тесты; LCG по модулю 2, который возвращает старшие 32 бита, проходит пакет SmallCrush от TestU01 , [ нужна ссылка ] , а 96-битный LCG проходит самый строгий пакет BigCrush. [35]
В конкретном примере ожидается, что идеальный генератор случайных чисел с 32-битным выходным сигналом (согласно теореме Дня рождения ) начнет дублировать более ранние выходные данные после √ m ≈ 2 16 результатов. Любой ГПСЧ, выходные данные которого представляют собой его полное, необрезанное состояние, не будет создавать дубликаты до тех пор, пока не истечет его полный период, что является легко обнаруживаемым статистическим недостатком. По связанным с этим причинам любой ГПСЧ должен иметь период, превышающий квадрат количества требуемых выходных данных. Учитывая скорость современных компьютеров, это означает период 2 64 для всех приложений, кроме наименее требовательных, и более длительный для требовательных симуляций.
Один недостаток, характерный для LCG, заключается в том, что, если они используются для выбора точек в n-мерном пространстве, точки будут лежать не более чем на n √ n !⋅ m гиперплоскостях ( теорема Марсальи , разработанная Джорджем Марсалья ). [7] Это связано с последовательной корреляцией между последовательными значениями последовательности X n . Небрежно выбранные множители обычно имеют гораздо меньше широко расположенных плоскостей, что может привести к проблемам. Спектральный тест , который представляет собой простой тест качества LCG, измеряет это расстояние и позволяет выбрать хороший множитель.
Расстояние между плоскостями зависит как от модуля, так и от множителя. Достаточно большой модуль может уменьшить это расстояние ниже разрешения чисел двойной точности. Выбор множителя становится менее важным, когда модуль велик. Спектральный индекс еще нужно вычислить и убедиться, что множитель неплохой, но чисто вероятностно становится крайне маловероятно встретить плохой множитель, когда модуль больше примерно 2 64 .
Еще одним недостатком, характерным для LCG, является короткий период младших битов, когда m выбрано равным степени 2. Это можно смягчить, используя модуль, больший, чем требуемый выходной сигнал, и используя наиболее значимые биты состояния.
Тем не менее, для некоторых приложений LCG могут быть хорошим вариантом. Например, во встроенной системе объем доступной памяти часто сильно ограничен. Точно так же в такой среде, как игровая консоль, вполне может быть достаточно небольшого количества старших битов LCG. (Младшие биты LCG, когда m является степенью 2, никогда не следует полагаться на какую-либо степень случайности.) Младшие биты проходят через очень короткие циклы. В частности, любой LCG полного цикла, когда m является степенью 2, будет выдавать попеременно нечетные и четные результаты.
LCG следует очень тщательно оценивать на предмет их пригодности для некриптографических приложений, где высокое качество случайности имеет решающее значение. Для моделирования Монте-Карло LCG должен использовать модуль, больший и желательно намного больший, чем куб количества необходимых случайных выборок. Это означает, например, что (хороший) 32-битный LCG можно использовать для получения около тысячи случайных чисел; 64-битный LCG подходит примерно для 2 21 случайной выборки (чуть более двух миллионов) и т. д. По этой причине на практике LCG не подходят для крупномасштабного моделирования Монте-Карло.
Ниже приведена реализация LCG на Python в виде генератора :
из коллекции.abc Генератор импорта def lcg ( modulus : int , a : int , c : int , seed : int ) -> Генератор [ int , None , None ]: """Линейный конгруэнтный генератор.""" while True : seed = ( a * seed + в ) % модуля выхода семян
Free Pascal использует Mersenne Twister в качестве генератора псевдослучайных чисел по умолчанию, тогда как Delphi использует LCG. Вот пример, совместимый с Delphi, в Free Pascal , основанный на информации из таблицы выше. Учитывая то же значение RandSeed, он генерирует ту же последовательность случайных чисел, что и Delphi.
единица lcg_random ; {$ifdef fpc}{$mode delphi}{$endif} интерфейс функция LCGRandom : расширенная ; перегрузка ; в соответствии ; функция LCGRandom ( const range : longint ) : longint ; перегрузка ; в соответствии ; функция реализации IM : кардинальная ; в соответствии ; начать RandSeed := RandSeed * 134775813 + 1 ; Результат := RandSeed ; конец ; функция LCGRandom : расширенная ; перегрузка ; в соответствии ; начать результат := IM * 2.32830643653870e-10 ; конец ; функция LCGRandom ( const range : longint ) : longint ; перегрузка ; в соответствии ; начало результата := IM * диапазон шр 32 ; конец ;
Как и всем генераторам псевдослучайных чисел, LCG необходимо сохранять состояние и изменять его каждый раз, когда генерирует новое число. Несколько потоков могут получить доступ к этому состоянию одновременно, вызывая состояние гонки. Реализации должны использовать разные состояния, каждое из которых имеет уникальную инициализацию для разных потоков, чтобы избежать одинаковых последовательностей случайных чисел при одновременном выполнении потоков.
Существует несколько генераторов, которые являются линейными конгруэнтными генераторами в другой форме, и поэтому к ним можно применить методы, используемые для анализа LCG.
Одним из методов получения более длительного периода является суммирование результатов нескольких LCG разных периодов, имеющих большое наименьшее общее кратное ; генератор Вихмана – Хилла является примером этой формы. (Мы бы предпочли, чтобы они были полностью взаимно простыми , но простой модуль подразумевает четный период, поэтому должен быть как минимум общий делитель, равный 2.) Можно показать, что это эквивалентно одному LCG с модулем, равным произведение компонентных модулей LCG.
ГПСЧ Марсальи со сложением и переносом и вычитанием с заимствованием с размером слова b = 2 w и задержками r и s ( r > s ) эквивалентны LCG с модулем br ± b s ± 1. [36] [37]
ГПСЧ умножения с переносом с множителем a эквивалентны LCG с большим простым модулем ab r -1 и множителем степени 2 b .
Конгруэнтный генератор с перестановкой начинается с LCG со степенью 2 модуля и применяет выходное преобразование для устранения проблемы короткого периода в младших битах.
Другим широко используемым примитивом для получения псевдослучайных последовательностей с длинным периодом является конструкция регистра сдвига с линейной обратной связью , которая основана на арифметике в GF(2)[ x ], кольце полиномов над GF(2) . Вместо сложения и умножения целых чисел основными операциями являются умножение с исключающим или и без переноса , которое обычно реализуется как последовательность логических сдвигов . Их преимущество состоит в том, что все их биты имеют полный период; они не страдают от слабости младших битов, от которой страдает арифметика по модулю 2 k . [38]
Примеры этого семейства включают генераторы xorshift и твистер Мерсенна . Последний обеспечивает очень длительный период (2 19937 −1) и вариативную однородность, но не проходит некоторые статистические тесты. [39] Генераторы Фибоначчи с запаздыванием также попадают в эту категорию; хотя они используют арифметическое сложение, их период обеспечивается LFSR среди младших битов.
Структуру регистра сдвига с линейной обратной связью легко обнаружить с помощью соответствующих тестов [40] , таких как тест линейной сложности, реализованный в пакете TestU01 ; булева циркулянтная матрица , инициализированная последовательными битами LFSR, никогда не будет иметь ранг выше степени полинома. Добавление функции нелинейного выходного микширования (как в конструкции xoshiro256** и перестановочных конгруэнтных генераторов ) может значительно улучшить производительность статистических тестов.
Другая структура ГПСЧ — это очень простая функция повторения в сочетании с мощной функцией выходного микширования. Сюда входят блочные шифры в режиме счетчика и некриптографические генераторы, такие как SplitMix64.
Структура, аналогичная LCG, но не эквивалентная ей, представляет собой многорекурсивный генератор: X n = ( a 1 X n −1 + a 2 X n −2 + ··· + a k X n − k ) mod m for k ≥ 2. При простом модуле это может генерировать периоды до m k −1, что является полезным расширением структуры LCG на более крупные периоды.
Мощный метод генерации высококачественных псевдослучайных чисел — объединение двух или более ГПСЧ различной структуры; сумма LFSR и LCG (как в конструкциях KISS или xorwow ) может работать очень хорошо при некоторой стоимости скорости.
На данный момент маловероятно, что ставшие традиционными названия будут исправлены.Математика вычислений (в печати). Соответствующие данные доступны по адресу https://github.com/vigna/CPRNG.
Множитель размером примерно
√
m
выдает случайные числа с плохим одномерным распределением.
{{citation}}
: CS1 maint: numeric names: authors list (link)