Pseudo-random number generation
Библиотека случайных чисел предоставляет классы, генерирующие случайные и псевдослучайные числа. Эти классы включают:
- Равномерные генераторы случайных битов (URBG), которые включают как генераторы случайных чисел (псевдослучайные генераторы, создающие целочисленные последовательности с равномерным распределением), так и генераторы истинно случайных чисел (если доступны).
- Распределения случайных чисел (например, uniform , normal , или poisson distributions ), которые преобразуют выходные данные URBG в различные статистические распределения.
Универсальные генераторы случайных чисел (URBG) и распределения предназначены для совместного использования при генерации случайных значений. Все генераторы случайных чисел могут быть явно инициализированы начальным значением, сериализованы и десериализованы для использования в повторяемых симуляторах.
Содержание |
Равномерные генераторы случайных битов
Равномерный генератор случайных битов — это функциональный объект, возвращающий беззнаковые целочисленные значения, причём каждое значение в диапазоне возможных результатов имеет (в идеале) равную вероятность быть возвращённым.
Все генераторы равномерно распределенных случайных битов удовлетворяют
UniformRandomBitGenerator
требованиям.
C++20 также определяет
uniform_random_bit_generator
концепт.
|
Определено в заголовке
<random>
|
|
|
(C++20)
|
определяет, что тип соответствует требованиям генератора равномерно распределенных случайных битов
(концепт) |
Генераторы случайных чисел
Генератор случайных чисел (обычно сокращается до генератора ) — это равномерный генератор случайных битов, который генерирует псевдослучайные числа, используя начальное значение (seed) в качестве источника энтропии.
В любой момент времени, механизм
e
типа
E
имеет состояние
e
i
для некоторого неотрицательного целого числа
i
. При конструировании,
e
имеет начальное состояние
e
0
, которое определяется параметрами механизма и начальным зерном (или последовательностью зерен).
Следующие свойства всегда определены для любого типа движка
E
:
-
Размер
состояния
Eв единицах размераE::result_type(т.е. ( sizeof ei) / sizeof ( E :: result_type ) ). -
Алгоритм перехода
TA
, с помощью которого состояние
e
e
iпереходит в следующее состояние ei+1(т.е. TA ( ei) == ei+1). -
Алгоритм генерации
GA
, с помощью которого состояние
e
отображается в значение типа
E::result_type, результат является псевдослучайным числом.
Псевдослучайная последовательность чисел может быть сгенерирована путем попеременного вызова TA и GA .
Стандартная библиотека предоставляет реализации трех различных классов алгоритмов генерации псевдослучайных чисел в виде шаблонов классов, что позволяет настраивать алгоритмы. Выбор того, какой движок использовать, включает ряд компромиссов:
- Линейный конгруэнтный генератор обладает умеренной скоростью и требует очень мало памяти для хранения состояния.
- Вихрь Мерсенна работает медленнее и требует больше памяти для хранения состояния, но при правильных параметрах обладает самой длинной неповторяющейся последовательностью с наилучшими спектральными характеристиками (для данного определения "наилучших").
- Генератор с вычитанием и переносом работает очень быстро даже на процессорах без расширенных наборов арифметических инструкций, ценой большего расхода памяти и иногда менее оптимальных спектральных характеристик.
|
(начиная с C++26) |
Ни один из этих генераторов случайных чисел не является
криптографически стойким
. Как и при любой защищённой операции, для этой цели следует использовать криптографическую библиотеку (например,
OpenSSL
RAND_bytes
).
Все типы, созданные из этих шаблонов, соответствуют RandomNumberEngine требованиям.
|
Определено в заголовке
<random>
|
|
|
(C++11)
|
реализует
линейный конгруэнтный
алгоритм
(шаблон класса) |
|
(C++11)
|
реализует
алгоритм Вихрь Мерсенна
(шаблон класса) |
|
(C++11)
|
реализует алгоритм вычитания с переносом (
запаздывающий Фибоначчи
)
(шаблон класса) |
|
(C++26)
|
счётчиковый параллелизуемый генератор
(шаблон класса) |
Адаптеры генераторов случайных чисел
Адаптеры генераторов случайных чисел генерируют псевдослучайные числа, используя другой генератор случайных чисел в качестве источника энтропии. Обычно они применяются для изменения спектральных характеристик базового генератора.
|
Определено в заголовочном файле
<random>
|
|
|
(C++11)
|
отбрасывает часть вывода генератора случайных чисел
(шаблон класса) |
|
(C++11)
|
упаковывает вывод генератора случайных чисел в блоки заданного количества бит
(шаблон класса) |
|
(C++11)
|
выводит результат работы генератора случайных чисел в другом порядке
(шаблон класса) |
Предопределенные генераторы случайных чисел
Несколько конкретных популярных алгоритмов предопределены.
|
Определено в заголовочном файле
<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
,
|
mt19937
(C++11)
|
std::
mersenne_twister_engine
<
std::
uint_fast32_t
,
|
mt19937_64
(C++11)
|
std::
mersenne_twister_engine
<
std::
uint_fast64_t
,
|
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 с применением псевдослучайного генератора, если отсутствует поддержка недетерминированной генерации случайных чисел.
|
(C++11)
|
недетерминированный генератор случайных чисел, использующий аппаратный источник энтропии
(класс) |
Распределения случайных чисел
Распределение случайных чисел обрабатывает выходные данные ГСЧ таким образом, чтобы результирующие данные распределялись в соответствии с заданной статистической функцией плотности вероятности.
Распределения случайных чисел удовлетворяют RandomNumberDistribution .
|
Определено в заголовочном файле
<random>
|
|
Равномерные распределения |
|
|
(C++11)
|
генерирует целочисленные значения, равномерно распределенные в заданном диапазоне
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения, равномерно распределенные в заданном диапазоне
(шаблон класса) |
Распределения Бернулли |
|
|
(C++11)
|
генерирует
bool
значения по
распределению Бернулли
(класс) |
|
(C++11)
|
генерирует целочисленные значения согласно
биномиальному распределению
(шаблон класса) |
|
(C++11)
|
генерирует целочисленные значения согласно
отрицательному биномиальному распределению
(шаблон класса) |
|
(C++11)
|
генерирует целочисленные значения согласно
геометрическому распределению
(шаблон класса) |
Распределения Пуассона |
|
|
(C++11)
|
генерирует целочисленные значения согласно
распределению Пуассона
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения по
экспоненциальному распределению
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения согласно
гамма-распределению
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения по
распределению Вейбулла
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения по
распределению экстремальных значений
(шаблон класса) |
Нормальные распределения |
|
|
(C++11)
|
генерирует вещественные значения с
стандартным нормальным (Гауссовым) распределением
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения с
логнормальным распределением
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения согласно
распределению хи-квадрат
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения по
распределению Коши
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения согласно
F-распределению Фишера
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения согласно
t-распределению Стьюдента
(шаблон класса) |
Выборочные распределения |
|
|
(C++11)
|
генерирует целочисленные значения по дискретному распределению
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения, распределенные на постоянных подинтервалах
(шаблон класса) |
|
(C++11)
|
генерирует вещественные значения, распределенные по определенным подинтервалам
(шаблон класса) |
Утилиты
|
Определено в заголовочном файле
<random>
|
|
|
(C++11)
|
равномерно распределяет вещественные значения заданной точности в диапазоне
[
0
,
1
)
(шаблон функции) |
|
(C++11)
|
универсальный генератор скремблированной последовательности затравки с устранением смещения
(класс) |
Алгоритмы генерации случайных чисел
|
Определено в заголовочном файле
<random>
|
|
|
(C++26)
|
заполняет диапазон случайными числами от равномерного генератора случайных битов
(функциональный объект алгоритма) |
Библиотека случайных чисел 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
для
Генерации псевдослучайных чисел
|