EssayAI
Блог
Блог
Математика и алгоритмы

Линейный конгруэнтный генератор: формула и период

11 июня 2026Время чтения: 8 минут
#линейный конгруэнтный генератор#псевдослучайные числа#теорема Халла-Добелла#период генератора#алгоритм
Линейный конгруэнтный генератор: формула и период

Линейный конгруэнтный генератор (ЛКГ) - это простейший алгоритм получения псевдослучайных чисел, который задаётся всего одной рекуррентной формулой и при этом лежит в основе генераторов стандартных библиотек языков C, Java и Pascal. Разобраться, как он работает, нужно каждому, кто изучает теорию вероятностей, дискретную математику или пишет собственные алгоритмы тестирования. Покрути параметры в калькуляторе ниже - он сразу покажет последовательность и диаграмму рассеяния, а потом мы разберём каждую формулу строго.

Формула линейного конгруэнтного генератора

В основе ЛКГ лежит одна рекуррентная формула:

Xn+1=(aXn+c)modm,X_{n+1} = (a \cdot X_n + c) \bmod m,

где aa - множитель (мультипликативная константа), cc - приращение (инкремент), mm - модуль, X0X_0 - начальное значение, называемое зерном или «seed». Каждый следующий элемент порождается из предыдущего умножением на aa, прибавлением cc и взятием остатка от деления на mm. Все числа последовательности лежат в диапазоне от 00 до m1m - 1.

Если c=0c = 0, генератор называют мультипликативным конгруэнтным генератором (МКГ); если c0c \neq 0 - смешанным или полным ЛКГ. Мультипликативный вариант не может породить 00 (иначе вся последовательность заглохнет), а смешанный допускает любое начальное зерно.

Последовательность ЛКГ с параметрами a=5, c=3, m=16 от X0=0: видно, как 16 точек равномерно покрывают диапазон 0-15 за один полный период, а при смене a диаграмма рассеяния показывает наклон линейной структуры

Период генератора и теорема Халла-Добелла

Главная характеристика ЛКГ - длина периода TT: через TT шагов последовательность начнёт повторяться. Максимально возможный период равен mm. Наивный выбор aa и cc легко даёт маленький период - например, при a=2,c=0,m=16,X0=1a=2, c=0, m=16, X_0=1 последовательность имеет период всего 11 (зациклится на 00 через несколько шагов).

Теорема Халла-Добелла (Hull-Dobell, 1962) полностью описывает, когда смешанный ЛКГ достигает периода mm:

T=m    {gcd(c,m)=1,a1(modp) для каждого простого pm,a1(mod4) если 4m.T = m \iff \begin{cases} \gcd(c, m) = 1, \\ a \equiv 1 \pmod{p} \text{ для каждого простого } p \mid m, \\ a \equiv 1 \pmod{4} \text{ если } 4 \mid m. \end{cases}

Другими словами: cc должно быть взаимно простым с mm; множитель a1a - 1 должен делиться на все простые делители mm; а если mm делится на 44, то и a1a - 1 обязан делиться на 44. Если хотя бы одно из условий нарушено, период окажется строго меньше mm.

Диаграмма рассеяния ЛКГ (Xn, Xn+1): точки ложатся на параллельные прямые - наглядное проявление гиперплоскостной структуры генератора
Диаграмма рассеяния ЛКГ (Xn, Xn+1): точки ложатся на параллельные прямые - наглядное проявление гиперплоскостной структуры генератора

На диаграмме рассеяния пары (Xn,Xn+1)(X_n, X_{n+1}) всегда ложатся на конечное число параллельных прямых - это не дефект реализации, а фундаментальное свойство линейных конгруэнтных генераторов, доказанное в теореме Марсальи (1968). Число прямых равно m2\sqrt[2]{m} в двумерном случае и убывает в высших размерностях.

Спектральный тест и качество генератора

Диаграмма рассеяния - простейший визуальный тест качества. Более строгий инструмент - спектральный тест: он измеряет расстояние между соседними параллельными гиперплоскостями в kk-мерном пространстве, на которые укладываются наборы (Xn,Xn+1,,Xn+k1)(X_n, X_{n+1}, \ldots, X_{n+k-1}). Чем больше это расстояние, тем хуже генератор: он порождает числа, которые имеют заметную решёточную структуру, а не распределены равномерно.

Для классического генератора стандарта ANSI C (a=1103515245a = 1\,103\,515\,245, c=12345c = 12\,345, m=232m = 2^{32}) спектральный тест выявляет плохую трёхмерную структуру - тройки чисел ложатся всего на 15 плоскостей. Именно поэтому современные стандарты вроде PCG или xorshift заменили ЛКГ более сложными конструкциями, хотя и надстроенными поверх той же базовой идеи.

Стандартные параметры в языках программирования

ЛКГ был основным PRNG в системных библиотеках на протяжении десятилетий:

Системаaaccmm
ANSI C (rand)1 103 515 24512 3452322^{32}
Java (java.util.Random)25 214 903 917112482^{48}
Borland C++22 695 47712322^{32}
MMIX (Кнут)6 364 136 223 846 793 0051 442 695 040 888 963 4072642^{64}

Обратите внимание: почти везде mm - степень двойки. Это удобно для реализации на двоичных ЭВМ: операция mod 2^k выполняется через побитовое И (& (m-1)), то есть без деления. Младшие биты выходной последовательности при степени двойки в модуле имеют значительно меньший период: бит kk имеет период 2k+12^{k+1}. Из-за этого в коде rand() % 2 (чётность) ANSI C даёт чередование 0,1,0,1,... - это не случайность, это закономерное следствие структуры генератора.

Пример вычисления вручную

Рассмотрим учебный пример: a=5a = 5, c=3c = 3, m=16m = 16, X0=0X_0 = 0.

X1=(50+3)mod16=3,X_1 = (5 \cdot 0 + 3) \bmod 16 = 3, X2=(53+3)mod16=18mod16=2,X_2 = (5 \cdot 3 + 3) \bmod 16 = 18 \bmod 16 = 2, X3=(52+3)mod16=13,X_3 = (5 \cdot 2 + 3) \bmod 16 = 13, X4=(513+3)mod16=68mod16=4.X_4 = (5 \cdot 13 + 3) \bmod 16 = 68 \bmod 16 = 4.

Продолжая, получаем последовательность: 0,3,2,13,4,7,6,1,8,11,10,5,12,15,14,90, 3, 2, 13, 4, 7, 6, 1, 8, 11, 10, 5, 12, 15, 14, 9, а затем снова 00. Период равен 16=m16 = m. Проверим условия Халла-Добелла: gcd(3,16)=1\gcd(3, 16) = 1 (выполнено); m=16=24m = 16 = 2^4, единственный простой делитель - 22, a1=4a - 1 = 4 делится на 22 (выполнено) и на 44 (выполнено). Все три условия в силе - отсюда и полный период.

Частые ошибки

  • Подстановка c=0c = 0 без проверки периода. Мультипликативный ЛКГ (c=0c = 0) не имеет периода mm ни при каких aa и m=2km = 2^k: нулевое зерно даёт постоянную нулевую последовательность, а ненулевые зёрна дают период не более m/4m/4. Для степеней двойки мультипликативный генератор работает только если зерно нечётно.
  • Перемешивание знаков при операции mod. В C и C++ оператор % для отрицательных чисел даёт отрицательный остаток. Если промежуточное значение aXn+ca \cdot X_n + c переполняет int, результат непредсказуем. Используй unsigned long или явный ((a * x + c) % m + m) % m.
  • Использование младших битов. При m=2km = 2^k младший бит меняется с периодом 22, следующие с периодом 44 и т.д. Для отбора случайного числа из [0,N)[0, N) всегда берите старшие биты: (lcg() >> 16) % N, а не lcg() % N.
  • Зависимость последовательности от зерна. Зерно полностью определяет всю последовательность. Если программа использует одно и то же начальное значение (например, X0=1X_0 = 1 жёстко прошито), «случайные» числа одинаковы в каждом запуске.
  • Ожидание криптостойкости. ЛКГ - не криптографический PRNG. Зная kk последовательных выходов, можно восстановить aa, cc и mm с помощью алгоритма, работающего за полиномиальное время. Для нужд криптографии применяют CSPRNG.

FAQ

Как выбрать параметры ЛКГ для максимального периода? Используй теорему Халла-Добелла: gcd(c,m)=1\gcd(c, m) = 1; a1a - 1 делится на все простые множители mm; если 4m4 \mid m, то 4a14 \mid a - 1. При m=232m = 2^{32} хороший выбор: a=1664525a = 1\,664\,525, c=1013904223c = 1\,013\,904\,223 (параметры Numerical Recipes). Проверить период легко в калькуляторе выше - выбери пресет или введи собственные значения.

Чем ЛКГ отличается от вихря Мерсенна? Вихрь Мерсенна (Mersenne Twister) имеет период 21993712^{19937} - 1 против m264m \le 2^{64} у типичного ЛКГ. MT проходит спектральный тест в 623 измерениях, тогда как ЛКГ рассыпается уже в 3-10 измерениях. При этом ЛКГ занимает в памяти всего одно число состояния и исполняется за 2-3 операции, а MT требует 625 слов состояния.

Почему диаграмма рассеяния ЛКГ показывает прямые линии? Это прямое следствие линейности формулы: Xn+1=aXn+c(modm)X_{n+1} = a \cdot X_n + c \pmod{m}. Каждое значение Xn+1X_{n+1} линейно зависит от XnX_n, поэтому пара (Xn,Xn+1)(X_n, X_{n+1}) лежит на прямой y=ax+cy = ax + c в кольце Zm\mathbb{Z}_m. При конечном mm прямая «заворачивается» и распадается на несколько параллельных отрезков. Число таких линий - мера качества генератора в спектральном тесте.

Коротко

Линейный конгруэнтный генератор порождает последовательность псевдослучайных чисел по формуле Xn+1=(aXn+c)modmX_{n+1} = (a \cdot X_n + c) \bmod m. Максимальный период mm достигается тогда и только тогда, когда выполнены условия теоремы Халла-Добелла: cc взаимно просто с mm, а a1a - 1 делится на все простые делители mm (и дополнительно на 4, если 4m4 \mid m). Главный недостаток ЛКГ - гиперплоскостная структура, видимая на диаграмме рассеяния и разрушающая многомерную равномерность. Тем не менее ЛКГ остаётся стандартом во многих учебных и системных реализациях из-за предельной простоты и высокой скорости.

Доверьте текст нейросети EssayAI

Открыть EssayAI

Бесплатно, на русском языке и без VPN

Читайте также