我的程序需要生成某个范围内的许多随机整数(int min,int max)。每次调用都会有一个不同的范围。什么是一个好的(最好是线程安全的)方法来做到这一点?以下不是线程安全的(并且使用 rand(),人们似乎不鼓励这样做):
int intRand(const int & min, const int & max)
{
return (rand() % (max+1-min)) + min;
}
This is much速度较慢,但使用<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 。但是,我正在做统计工作,所以我希望数字来自尽可能无偏的分布(例如,如果使用的分布范围不是(最大-最小)的倍数,则分布将略有不同)有偏见)。这是一个选择,但我再次想避免它。
SOLUTION该解决方案来自 @konrad-rudolph @mark-ransom 和 @mathk 的答案。随机数生成器的播种是为了满足我的特殊需要。更常见的方法是使用 time(NULL)。如果您在同一秒内创建许多线程,那么它们将获得相同的种子。即使使用clock(),这也是一个问题,因此我们包含线程ID。一个缺点——这会泄漏内存--- 每个线程一个生成器。
#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);
}