Моя программа должна генерировать множество случайных целых чисел в некотором диапазоне (int min, int max). Каждый вызов будет иметь другой диапазон. Что такое хороший (предпочтительно поточно-безопасный) способ сделать это? Следующее не является потокобезопасным (и использует rand(), который люди, похоже, препятствуют):
int intRand(const int & min, const int & max)
{
return (rand() % (max+1-min)) + min;
}
Это намного медленнее, но использует <random>
:
int intRand(const int & min, const int & max) {
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(min,max);
return distribution(generator);
}
Что-то вроде этого - то, что я собираюсь (функция changeParameters не существует):
int intRand(const int & min, const int & max) {
static std::default_random_engine generator;
static std::uniform_int_distribution<int> distribution(0, 10);
distribution.changeParameters(min, max);
return distribution(generator);
}
Другой вариант - сделать широкий диапазон на uniform_int_distribution
, а затем использовать mod, как в первом примере. Тем не менее, я занимаюсь статистической работой, поэтому я хочу, чтобы числа исходили из непредсказуемого распределения (например, если диапазон используемого распределения не кратен (max-min), распределение будет немного предвзято). Это вариант, но опять же, я бы хотел его избежать.
РЕШЕНИЕ. Это решение исходит из ответов @konrad-rudolph @mark-ransom и @mathk. Посев генератора случайных чисел выполняется в соответствии с моими конкретными потребностями. Более общий подход заключается в использовании времени (NULL). Если вы сделаете много потоков за одну секунду, они тогда получат одно и то же семя. Даже с clock() это проблема, поэтому мы включаем идентификатор потока. Недостаток - это утечка памяти - один генератор на поток.
#if defined (_MSC_VER) // Visual studio
#define thread_local __declspec( thread )
#elif defined (__GCC__) // GCC
#define thread_local __thread
#endif
#include <random>
#include <time.h>
#include <thread>
using namespace std;
/* Thread-safe function that returns a random number between min and max (inclusive).
This function takes ~142% the time that calling rand() would take. For this extra
cost you get a better uniform distribution and thread-safety. */
int intRand(const int & min, const int & max) {
static thread_local mt19937* generator = nullptr;
if (!generator) generator = new mt19937(clock() + this_thread::get_id().hash());
uniform_int_distribution<int> distribution(min, max);
return distribution(*generator);
}