C++
Генерация случайных чисел
Поиск…
замечания
Генерация случайных чисел в C ++ обеспечивается заголовком <random>
. Этот заголовок определяет случайные устройства, псевдослучайные генераторы и распределения.
Случайные устройства возвращают случайные числа, предоставляемые операционной системой. Они должны либо использоваться для инициализации псевдослучайных генераторов, либо непосредственно для криптографических целей.
Псевдослучайные генераторы возвращают целочисленные псевдослучайные числа, основанные на их исходном семени. Диапазон псевдослучайных чисел обычно охватывает все значения неподписанного типа. Все псевдослучайные генераторы в стандартной библиотеке возвращают одинаковые числа для одного и того же начального семестра для всех платформ.
Распределения потребляют случайные числа от псевдослучайных генераторов или случайных устройств и производят случайные числа с необходимым распределением. Распределения не являются независимыми от платформы и могут создавать разные числа для тех же генераторов с одинаковыми начальными семенами на разных платформах.
Истинное генератор случайных значений
Чтобы генерировать истинные случайные значения, которые могут использоваться для криптографии, std::random_device
должен использоваться как генератор.
#include <iostream>
#include <random>
int main()
{
std::random_device crypto_random_generator;
std::uniform_int_distribution<int> int_distribution(0,9);
int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10000; i++) {
int result = int_distribution(crypto_random_generator);
actual_distribution[result]++;
}
for(int i = 0; i < 10; i++) {
std::cout << actual_distribution[i] << " ";
}
return 0;
}
std::random_device
используется так же, как используется генератор псевдослучайных значений.
Однако std::random_device
может быть реализовано в терминах механизма псевдослучайного числа, определенного для реализации, если для реализации не доступен недетерминированный источник (например, аппаратное устройство).
Обнаружение таких реализаций должно быть возможно через функцию члена entropy
(которая возвращает ноль, когда генератор полностью детерминирован), но многие популярные библиотеки (как libstdc ++, так и LLVM LCC), всегда возвращают ноль, даже если они используют высококачественную внешнюю случайность ,
Создание псевдослучайного числа
Генератор псевдослучайных чисел генерирует значения, которые можно угадать на основе ранее сгенерированных значений. Другими словами: он детерминирован. Не используйте генератор псевдослучайных чисел в ситуациях, когда требуется истинное случайное число.
#include <iostream>
#include <random>
int main()
{
std::default_random_engine pseudo_random_generator;
std::uniform_int_distribution<int> int_distribution(0, 9);
int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10000; i++) {
int result = int_distribution(pseudo_random_generator);
actual_distribution[result]++;
}
for(int i = 0; i <= 9; i++) {
std::cout << actual_distribution[i] << " ";
}
return 0;
}
Этот код создает генератор случайных чисел и распределение, которое генерирует целые числа в диапазоне [0,9] с равным правдоподобием. Затем он подсчитывает, сколько раз каждый результат был сгенерирован.
Параметр шаблона std::uniform_int_distribution<T>
указывает тип целого, который должен быть сгенерирован. Используйте std::uniform_real_distribution<T>
для создания поплавков или удвоений.
Использование генератора для множества распределений
Генератор случайных чисел может (и должен) использоваться для нескольких распределений.
#include <iostream>
#include <random>
int main()
{
std::default_random_engine pseudo_random_generator;
std::uniform_int_distribution<int> int_distribution(0, 9);
std::uniform_real_distribution<float> float_distribution(0.0, 1.0);
std::discrete_distribution<int> rigged_dice({1,1,1,1,1,100});
std::cout << int_distribution(pseudo_random_generator) << std::endl;
std::cout << float_distribution(pseudo_random_generator) << std::endl;
std::cout << (rigged_dice(pseudo_random_generator) + 1) << std::endl;
return 0;
}
В этом примере определяется только один генератор. Затем он используется для генерации случайного значения в трех разных распределениях. Распределение rigged_dice
будет генерировать значение от 0 до 5, но почти всегда генерирует 5
, потому что вероятность создания 5
равна 100 / 105
.