Я хотел бы дополнить отличные ответы Angry Shoe и peterchen кратким обзором состояния дел в 2015 году:
Некоторые хорошие варианты
randutils
randutils
Библиотека (презентация) является интересной новинкой, предлагая простой интерфейс и (объявившего) надежные случайные возможности. У него есть недостатки, заключающиеся в том, что он добавляет зависимости от вашего проекта, и, будучи новым, он не был тщательно протестирован. В любом случае, поскольку он бесплатный (лицензия MIT) и предназначен только для заголовков, я думаю, что стоит попробовать.
Минимальный образец: бросок кубика
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
Даже если библиотека не интересует, на веб-сайте ( http://www.pcg-random.org/ ) можно найти много интересных статей на тему генерации случайных чисел в целом и библиотеки C ++ в частности.
Boost.Random
Boost.Random
(документация) является библиотекой , которая вдохновила C++11
«S <random>
, с которым разделяет большую часть интерфейса. Хотя теоретически также являясь внешней зависимостью, Boost
к настоящему времени имеет статус «квазистандартной» библиотеки, и ее Random
модуль можно рассматривать как классический выбор для генерации случайных чисел хорошего качества. Он имеет два преимущества по сравнению с C++11
решением:
- он более переносимый, ему просто нужна поддержка компилятора для C ++ 03
- его
random_device
методы использования системы , специфичные для предложения посевные хорошего качества
Единственный небольшой недостаток заключается в том, что модуль предлагает random_device
не только заголовок, его нужно компилировать и связывать boost_random
.
Минимальный образец: бросок кубика
#include <iostream>
#include <boost/random.hpp>
#include <boost/nondet_random.hpp>
int main() {
boost::random::random_device rand_dev;
boost::random::mt19937 generator(rand_dev());
boost::random::uniform_int_distribution<> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Хотя минимальный образец работает хорошо, в реальных программах следует добавить пару улучшений:
- сделать : генератор довольно пухлый (> 2 KB) и лучше не выделяется в стеке
mt19937
thread_local
- seed
mt19937
с более чем одним целым числом: Mersenne Twister имеет большое состояние и может использовать больше энтропии во время инициализации
Некоторые не очень хорошие варианты
Библиотека C ++ 11
Будучи наиболее идиоматическим решением, <random>
библиотека не предлагает многого в обмен на сложность своего интерфейса даже для базовых нужд. Недостаток заключается в std::random_device
том, что стандарт не требует минимального качества для своего вывода (при условии, что он entropy()
возвращает 0
), и с 2015 года MinGW (не самый используемый компилятор, но вряд ли эзотерический выбор) всегда будет печатать 4
на минимальном образце.
Минимальный образец: бросок кубика
#include <iostream>
#include <random>
int main() {
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<int> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Если реализация не гнилая, это решение должно быть эквивалентно решению Boost, и применимы те же предложения.
Решение Годо
Минимальный образец: бросок кубика
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
Это простое, эффективное и аккуратное решение. Единственный дефект, для компиляции потребуется время - около двух лет, при условии, что C ++ 17 будет выпущен вовремя и экспериментальная randint
функция будет утверждена в новом стандарте. Возможно, к тому времени улучшатся и гарантии качества посева.
Минимальный образец: бросок кубика
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
Старое решение C считается вредным, и по уважительным причинам (см. Другие ответы здесь или этот подробный анализ ). Тем не менее, у него есть свои преимущества: он простой, портативный, быстрый и честный, в том смысле, что известно, что получаемые случайные числа вряд ли являются приличными, и поэтому у человека нет соблазна использовать их для серьезных целей.
Решение бухгалтерского тролля
Минимальный образец: бросок кубика
#include <iostream>
int main() {
std::cout << 9;
}
Хотя 9 - несколько необычный результат для обычного броска кубика, нужно восхищаться превосходным сочетанием хороших качеств в этом решении, которое оказалось самым быстрым, простым, самым удобным для кеширования и самым портативным. Заменяя 9 на 4, можно получить идеальный генератор для любого типа подземелий и гибели драконов, при этом избегая при этом обозначенных символами значений 1, 2 и 3. Единственный небольшой недостаток заключается в том, что из-за дурного настроения бухгалтерских троллей Дилберта, эта программа фактически порождает неопределенное поведение.