Каков наилучший способ генерировать случайные числа в C ++? - PullRequest
14 голосов
/ 28 февраля 2012

Каков наилучший способ генерации случайных чисел?

Ответы [ 5 ]

25 голосов
/ 28 февраля 2012

Вы должны использовать <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, по сути с тем же интерфейсом (хотя есть небольшие различия).

12 голосов
/ 28 февраля 2012

Если и только если:

  • вы не ищете "идеальную однородность" или

  • у вас естьнет поддержки 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 уже.

5 голосов
/ 28 февраля 2012

Boost.Random - превосходная библиотека для создания псевдослучайных чисел (или действительно случайных, если платформа поддерживает это).

2 голосов
/ 28 февраля 2012

Если вы говорите о стандартной библиотеке C ++ до C ++ 11, rand и srand - ваши генераторы случайных чисел.Есть способы получить больше точности из этих функций, чем использование модуля с целочисленной арифметикой.Вы можете использовать удвоения, например, если высокая скорость не имеет значения, и округлить результаты до int.

Что касается пользовательских библиотек, если вы действительно хотите хорошее случайное распределение и скорость, воспользуйтесь Google Mersenne Twister.Есть также варианты в boost.

С C ++ 11 у вас есть <random>.http://en.cppreference.com/w/cpp/numeric/random

1 голос
/ 05 августа 2017

Моя «случайная» библиотека обеспечивает удобную оболочку вокруг случайных классов C ++ 11.Вы можете сделать почти все с помощью простого метода get.

Примеры:

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

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:

https://github.com/effolkronium/random

...