英文:
Where is it better to store random_device/mt19937?
问题
我有一个使用随机性的函数
void fun() {
random_device rd;
mt19937 gen(rd());
uniform_real_distribution<double> dis(0.0, 1.0);
// ...
}
而且,正如我怀疑的那样,如果反复调用它,并且每次都创建rd
和gen
,那么我将获得较差的随机性。将这些变量作为类的全局/私有字段是否更好,以便它们不会被多次重新声明?
英文:
I have a function which makes use of randomness
void fun() {
random_device rd;
mt19937 gen(rd());
uniform_real_distribution<double> dis(0.0, 1.0);
// ...
}
And, as I suspect, I'll get poor random if it's call repeatedly and both rd
and gen
are created each time. Is it better to make these variables global/private fields of a class so they are not redeclared multiple times?
答案1
得分: 1
你可以使用 random_device
生成一个种子来初始化 mt19937
。由于 random_device
是一个昂贵的操作,所以不需要每次调用函数时都调用它,也无需保存 random_device
。
mt19937
不是线程安全的。如果你的应用程序是单线程的,你可以将它保存为类的私有数据成员。然而,如果你的应用程序在多个线程中运行,最好将它设置为方法的线程局部变量。
void func() {
thread_local mt19937(random_device{}());
}
英文:
You can use random_device
to generate a seed to initialize mt19937
. Since random_device
is an expensive operation, no need to call it every time the function is called, and there's no need to save random_device
.
mt19937
is not thread safe. If your application is single-threaded, you can save it as a private data member of your class. However, if your application runs in multiple-thread, you'd better make it a thread local variable of the method.
void func() {
thread_local mt19937(random_device{}());
}
答案2
得分: 0
A random number generator should be a global object. But there is nothing wrong with burying it in a function for access:
template <typename RealType>
RealType random_real_in_range( RealType min = 0., RealType max = 1. )
{
thread_local std::mt19937 rng( std::random_device{}() );
return std::uniform_real_distribution<RealType>( min, max )( rng );
}
The drawback here is that MT really should be “warmed up” by calling .discard( 1000 )
or so...
英文:
A random number generator should be a global object. But there is nothing wrong with burying it in a function for access:
template <typename RealType>
RealType random_real_in_range( RealType min = 0., RealType max = 1. )
{
thread_local std::mt19937 rng( std::random_device{}() );
return std::uniform_real_distribution<RealType>( min, max )( rng );
}
The drawback here is that MT really should be “warmed up” by calling .discard( 1000 )
or so...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论