Я хотів би доповнити чудові відповіді 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 (Документація) є бібліотекою , яка надихнула 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';
}
Хоча мінімальна вибірка добре працює, реальні програми повинні використовувати пару вдосконалень:
- make
mt19937a thread_local: генератор досить пухкий (> 2 КБ) і краще не виділяти його в стек
- насіння
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);
}
Це просте, ефективне та акуратне рішення. Тільки дефект, компіляція займе деякий час - близько двох років, якщо С ++ 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; // http://dilbert.com/strip/2001-10-25
}
Незважаючи на те, що 9 є дещо незвичним результатом для звичайного рулону, слід захоплюватися чудовим поєднанням хороших якостей у цьому рішенні, яке вдається бути найшвидшим, найпростішим, найбільш зручним та керованим. Замінивши 9 на 4, ви отримуєте ідеальний генератор для будь-якого подземелля і помирання драконів, уникаючи при цьому символічно навантажених значень 1, 2 і 3. Єдиний невеликий недолік полягає в тому, що через поганий характер бухгалтерських тролів Ділберта, ця програма насправді породжує невизначену поведінку.