Каков наилучший способ генерировать случайные числа в 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.

Примеры:

  1. Случайное число в диапазоне

auto val = Random::get(-10, 10); // Integer
auto val = Random::get(10.f, -10.f); // Float point

  1. Случайный логический

auto val = Random::get<bool>( ) // 0.5% to generate true

auto val = Random::get<bool>( 0.7 ) // 0.7% to generate true

  1. Случайное значение из списка std::initilizer_list
auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
  1. Случайный итератор из диапазона итератора или всего контейнера

auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator

auto it = Random::get( vec ); // return random iterator

И даже больше вещей! Проверьте страницу GitHub:

https://github.com/effolkronium/random

Другие вопросы по тегам