Каков наилучший способ генерировать случайные числа в C++?
Каков наилучший способ генерировать случайные числа?
5 ответов
Если и только если:
Вы не ищете "идеальную однородность" или
у вас нет поддержки C++11 и даже TR1 (таким образом, у вас нет другого выбора)
тогда вы могли бы рассмотреть возможность использования следующего решения в стиле C, которое (ради репутации этого сообщества ~ см. rand() считает вредным) написано зачеркнутым шрифтом:
Вот простая функция в стиле C, которая генерирует случайное число из интервала min
в max
включительно. Эти цифры кажутся очень близкими к равномерному распределению.
int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}
и не забудьте позвонить srand
прежде чем использовать его:
int occurences[8] = {0};
srand(time(0));
for (int i = 0; i < 100000; ++i)
++occurences[irand(1,7)];
for (int i = 1; i <= 7; ++i)
printf("%d ", occurences[i]);
выход: 14253 14481 14210 14029 14289 14503 14235
Также посмотрите на:
Создать случайное число в пределах диапазона?
Генерация случайных чисел равномерно по всему диапазону
и найдите время и посмотрите хотя бы первые 11 минут вышеупомянутого видео
Иначе:
использование <random>
точно так же, как уже было указано Kerrek SB.
Вы должны использовать <random>
:
#include <random>
typedef std::mt19937 rng_type;
std::uniform_int_distribution<rng_type::result_type> udist(0, 7);
rng_type rng;
int main()
{
// seed rng first:
rng_type::result_type const seedval = get_seed(); // get this from somewhere
rng.seed(seedval);
rng_type::result_type random_number = udist(rng);
return random_number;
}
До C++11 вы можете найти это либо в TR1 (<tr1/random>
, std::tr1::mt19937
и т. д.) или в Boost.random с практически одинаковым интерфейсом (хотя есть и небольшие отличия).
Boost.Random - превосходная библиотека для создания псевдослучайных чисел (или действительно случайных, если платформа поддерживает это).
Если вы говорите о стандартной библиотеке C++ до C++11, rand и srand - ваши генераторы случайных чисел. Есть способы получить больше точности из этих функций, чем использование модуля с целочисленной арифметикой. Например, вы можете использовать double, если высокая скорость не имеет значения, и округлить результаты до int.
Что касается пользовательских библиотек, если вы действительно хотите хорошее случайное распределение и скорость, используйте Google Mersenne Twister. Есть также варианты в Boost.
С C++ 11 у вас есть <random>
, http://en.cppreference.com/w/cpp/numeric/random
Моя "случайная" библиотека обеспечивает удобную оболочку вокруг случайных классов C++11. Вы можете делать практически все с помощью простого метода get.
Примеры:
- Случайное число в диапазоне
auto val = Random::get(-10, 10); // Integer
auto val = Random::get(10.f, -10.f); // Float point
- Случайный логический
auto val = Random::get<bool>( ) // 0.5% to generate true
auto val = Random::get<bool>( 0.7 ) // 0.7% to generate true
- Случайное значение из списка std::initilizer_list
auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
- Случайный итератор из диапазона итератора или всего контейнера
auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator
auto it = Random::get( vec ); // return random iterator
И даже больше вещей! Проверьте страницу GitHub: