Namespaces
Variants

Pseudo-random number generation

From cppreference.net

Библиотека случайных чисел предоставляет классы, генерирующие случайные и псевдослучайные числа. Эти классы включают:

  • Равномерные генераторы случайных битов (URBG), которые включают как генераторы случайных чисел (псевдослучайные генераторы, создающие целочисленные последовательности с равномерным распределением), так и генераторы истинно случайных чисел (если доступны).
  • Распределения случайных чисел (например, uniform , normal , или poisson distributions ), которые преобразуют выходные данные URBG в различные статистические распределения.

Универсальные генераторы случайных чисел (URBG) и распределения предназначены для совместного использования при генерации случайных значений. Все генераторы случайных чисел могут быть явно инициализированы начальным значением, сериализованы и десериализованы для использования в повторяемых симуляторах.

Содержание

Равномерные генераторы случайных битов

Равномерный генератор случайных битов — это функциональный объект, возвращающий беззнаковые целочисленные значения, причём каждое значение в диапазоне возможных результатов имеет (в идеале) равную вероятность быть возвращённым.

Все генераторы равномерно распределенных случайных битов удовлетворяют UniformRandomBitGenerator требованиям. C++20 также определяет uniform_random_bit_generator концепт.

Определено в заголовке <random>
определяет, что тип соответствует требованиям генератора равномерно распределенных случайных битов
(концепт)

Генераторы случайных чисел

Генератор случайных чисел (обычно сокращается до генератора ) — это равномерный генератор случайных битов, который генерирует псевдослучайные числа, используя начальное значение (seed) в качестве источника энтропии.

В любой момент времени, механизм e типа E имеет состояние e i для некоторого неотрицательного целого числа i . При конструировании, e имеет начальное состояние e 0 , которое определяется параметрами механизма и начальным зерном (или последовательностью зерен).

Следующие свойства всегда определены для любого типа движка E :

  • Размер состояния E в единицах размера E::result_type (т.е. ( sizeof e i ) / sizeof ( E :: result_type ) ).
  • Алгоритм перехода TA , с помощью которого состояние e e i переходит в следующее состояние e i+1 (т.е. TA ( e i ) == e i+1 ).
  • Алгоритм генерации GA , с помощью которого состояние e отображается в значение типа E::result_type , результат является псевдослучайным числом.

Псевдослучайная последовательность чисел может быть сгенерирована путем попеременного вызова TA и GA .

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

  • Линейный конгруэнтный генератор обладает умеренной скоростью и требует очень мало памяти для хранения состояния.
  • Вихрь Мерсенна работает медленнее и требует больше памяти для хранения состояния, но при правильных параметрах обладает самой длинной неповторяющейся последовательностью с наилучшими спектральными характеристиками (для данного определения "наилучших").
  • Генератор с вычитанием и переносом работает очень быстро даже на процессорах без расширенных наборов арифметических инструкций, ценой большего расхода памяти и иногда менее оптимальных спектральных характеристик.
  • Движок Philox является счётчиковым генератором случайных чисел . Он имеет небольшое состояние и длинный период (не менее 2^130) и предназначен для использования в Монте-Карло моделировании, требующем массово-параллельной генерации случайных чисел. Он легко векторизуется и распараллеливается и реализован в оптимизированных для GPU библиотеках.
(начиная с C++26)

Ни один из этих генераторов случайных чисел не является криптографически стойким . Как и при любой защищённой операции, для этой цели следует использовать криптографическую библиотеку (например, OpenSSL RAND_bytes ).

Все типы, созданные из этих шаблонов, соответствуют RandomNumberEngine требованиям.

Определено в заголовке <random>
реализует линейный конгруэнтный алгоритм
(шаблон класса)
реализует алгоритм Вихрь Мерсенна
(шаблон класса)
реализует алгоритм вычитания с переносом ( запаздывающий Фибоначчи )
(шаблон класса)
счётчиковый параллелизуемый генератор
(шаблон класса)

Адаптеры генераторов случайных чисел

Адаптеры генераторов случайных чисел генерируют псевдослучайные числа, используя другой генератор случайных чисел в качестве источника энтропии. Обычно они применяются для изменения спектральных характеристик базового генератора.

Определено в заголовочном файле <random>
отбрасывает часть вывода генератора случайных чисел
(шаблон класса)
упаковывает вывод генератора случайных чисел в блоки заданного количества бит
(шаблон класса)
выводит результат работы генератора случайных чисел в другом порядке
(шаблон класса)

Предопределенные генераторы случайных чисел

Несколько конкретных популярных алгоритмов предопределены.

**Примечание:** В данном фрагменте HTML-кода отсутствует переводимый текст, который требовал бы перевода на русский язык. Все содержимое состоит из: - HTML-тегов и атрибутов (не подлежат переводу) - Кода C++ внутри тегов ` ` и ` ` (не подлежит переводу) - Числовых значений и шестнадцатеричных констант - Специфических терминов C++ (не подлежат переводу) Единственный текстовый элемент "(C++26)" является стандартным обозначением версии языка и также не требует перевода.
Определено в заголовочном файле <random>
Тип Определение
minstd_rand0 (C++11) std:: linear_congruential_engine < std:: uint_fast32_t ,
16807 , 0 , 2147483647 >

Обнаружен в 1969 году Льюисом, Гудманом и Миллером, принят как "Минимальный стандарт" в 1988 году Парком и Миллером

minstd_rand (C++11)

std:: linear_congruential_engine < std:: uint_fast32_t ,
48271 , 0 , 2147483647 >
Новый "Минимальный стандарт", рекомендованный Парком, Миллером и Стокмайером в 1993 году

mt19937 (C++11)

std:: mersenne_twister_engine < std:: uint_fast32_t ,
32 , 624 , 397 , 31 ,
0x9908b0df , 11 ,
0xffffffff , 7 ,
0x9d2c5680 , 15 ,
0xefc60000 , 18 , 1812433253 >
32-битный вихрь Мерсенна от Мацумото и Нисимуры, 1998

mt19937_64 (C++11)

std:: mersenne_twister_engine < std:: uint_fast64_t ,
64 , 312 , 156 , 31 ,
0xb5026f5aa96619e9 , 29 ,
0x5555555555555555 , 17 ,
0x71d67fffeda60000 , 37 ,
0xfff7eee000000000 , 43 ,
6364136223846793005 >
64-битный вихрь Мерсенна от Мацумото и Нисимуры, 2000

ranlux24_base (C++11) std:: subtract_with_carry_engine < std:: uint_fast32_t , 24 , 10 , 24 >
ranlux48_base (C++11) std:: subtract_with_carry_engine < std:: uint_fast64_t , 48 , 5 , 12 >
ranlux24 (C++11) std:: discard_block_engine < std:: ranlux24_base , 223 , 23 >

24-битный генератор RANLUX от Мартина Люшера и Фреда Джеймса, 1994

ranlux48 (C++11) std:: discard_block_engine < std:: ranlux48_base , 389 , 11 >

48-битный генератор RANLUX от Мартина Люшера и Фреда Джеймса, 1994

knuth_b (C++11) std:: shuffle_order_engine < std:: minstd_rand0 , 256 >
philox4x32 (C++26) std:: philox_engine < std:: uint_fast32_t , 32 , 4 , 10 ,
0xCD9E8D57 , 0x9E3779B9 ,
0xD2511F53 , 0xBB67AE85 >
philox4x64 (C++26) std:: philox_engine < std:: uint_fast64_t , 64 , 4 , 10 ,
0xCA5A826395121157 , 0x9E3779B97F4A7C15 ,
0xD2E7470EE14C6C93 , 0xBB67AE8584CAA73B >
default_random_engine (C++11) тип RandomNumberEngine с реализацией, определяемой реализацией

Недетерминированные случайные числа

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

недетерминированный генератор случайных чисел, использующий аппаратный источник энтропии
(класс)

Распределения случайных чисел

Распределение случайных чисел обрабатывает выходные данные ГСЧ таким образом, чтобы результирующие данные распределялись в соответствии с заданной статистической функцией плотности вероятности.

Распределения случайных чисел удовлетворяют RandomNumberDistribution .

Определено в заголовочном файле <random>
Равномерные распределения
генерирует целочисленные значения, равномерно распределенные в заданном диапазоне
(шаблон класса)
генерирует вещественные значения, равномерно распределенные в заданном диапазоне
(шаблон класса)
Распределения Бернулли
генерирует bool значения по распределению Бернулли
(класс)
генерирует целочисленные значения согласно биномиальному распределению
(шаблон класса)
генерирует целочисленные значения согласно отрицательному биномиальному распределению
(шаблон класса)
генерирует целочисленные значения согласно геометрическому распределению
(шаблон класса)
Распределения Пуассона
генерирует целочисленные значения согласно распределению Пуассона
(шаблон класса)
генерирует вещественные значения по экспоненциальному распределению
(шаблон класса)
генерирует вещественные значения согласно гамма-распределению
(шаблон класса)
генерирует вещественные значения по распределению Вейбулла
(шаблон класса)
генерирует вещественные значения по распределению экстремальных значений
(шаблон класса)
Нормальные распределения
генерирует вещественные значения с стандартным нормальным (Гауссовым) распределением
(шаблон класса)
генерирует вещественные значения с логнормальным распределением
(шаблон класса)
генерирует вещественные значения согласно распределению хи-квадрат
(шаблон класса)
генерирует вещественные значения по распределению Коши
(шаблон класса)
генерирует вещественные значения согласно F-распределению Фишера
(шаблон класса)
генерирует вещественные значения согласно t-распределению Стьюдента
(шаблон класса)
Выборочные распределения
генерирует целочисленные значения по дискретному распределению
(шаблон класса)
генерирует вещественные значения, распределенные на постоянных подинтервалах
(шаблон класса)
генерирует вещественные значения, распределенные по определенным подинтервалам
(шаблон класса)

Утилиты

Определено в заголовочном файле <random>
равномерно распределяет вещественные значения заданной точности в диапазоне [ 0 , 1 )
(шаблон функции)
(C++11)
универсальный генератор скремблированной последовательности затравки с устранением смещения
(класс)

Алгоритмы генерации случайных чисел

Определено в заголовочном файле <random>
заполняет диапазон случайными числами от равномерного генератора случайных битов
(функциональный объект алгоритма)

Библиотека случайных чисел C

В дополнение к движкам и распределениям, описанным выше, функции и константы из библиотеки случайных чисел C также доступны, хотя и не рекомендуются к использованию:

Определено в заголовочном файле <cstdlib>
генерирует псевдослучайное число
(функция)
инициализирует генератор псевдослучайных чисел
(функция)
максимальное возможное значение, генерируемое std::rand
(макроконстанта)

Пример

#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <random>
#include <string>
int main()
{
    // Инициализация генератора случайным значением, если доступно
    std::random_device r;
    // Выбор случайного среднего значения между 1 и 6
    std::default_random_engine e1(r());
    std::uniform_int_distribution<int> uniform_dist(1, 6);
    int mean = uniform_dist(e1);
    std::cout << "Случайно выбранное среднее: " << mean << '\n';
    // Генерация нормального распределения вокруг этого среднего
    std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937 e2(seed2);
    std::normal_distribution<> normal_dist(mean, 2);
    std::map<int, int> hist;
    for (int n = 0; n != 10000; ++n)
        ++hist[std::round(normal_dist(e2))];
    std::cout << "Нормальное распределение вокруг " << mean << ":\n"
              << std::fixed << std::setprecision(1);
    for (auto [x, y] : hist)
        std::cout << std::setw(2) << x << ' ' << std::string(y / 200, '*') << '\n';
}

Возможный вывод:

Случайно выбранное среднее: 4
Нормальное распределение вокруг 4:
-4
-3
-2
-1
 0 *
 1 ***
 2 ******
 3 ********
 4 *********
 5 ********
 6 ******
 7 ***
 8 *
 9
10
11
12

Смотрите также

Документация C для Генерации псевдослучайных чисел