我有一个利用随机性的函数
void fun() { random_device rd; mt19937 gen(rd()); uniform_real_distribution<double> dis(0.0, 1.0); // ... }
而且,正如我所怀疑的,如果它被重复调用,并且每次都创建rd和gen,那么我会得到很差的随机性。将这些变量设置为类的全局/私有字段,这样它们就不会被多次重新声明,是不是更好?
rd
gen
r8uurelv1#
可以使用random_device生成一个seed来初始化mt19937,由于random_device是一个开销很大的操作,所以不需要每次调用函数时都调用它,也不需要保存random_device。mt19937不是线程安全的。如果您的应用程序是单线程的,您可以将其保存为类的私有数据成员。但是,如果您的应用程序在多线程中运行,您最好将其设置为方法的线程局部变量。
random_device
mt19937
void func() { thread_local mt19937(random_device{}()); }
q5iwbnjs2#
随机数生成器 * 应该 * 是一个全局对象,但将其隐藏在一个函数中以供访问并没有什么错:
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 ); }
这里的缺点是MT真的应该通过调用.discard( 1000 )左右来“预热”...
.discard( 1000 )
2条答案
按热度按时间r8uurelv1#
可以使用
random_device
生成一个seed来初始化mt19937
,由于random_device
是一个开销很大的操作,所以不需要每次调用函数时都调用它,也不需要保存random_device
。mt19937
不是线程安全的。如果您的应用程序是单线程的,您可以将其保存为类的私有数据成员。但是,如果您的应用程序在多线程中运行,您最好将其设置为方法的线程局部变量。q5iwbnjs2#
随机数生成器 * 应该 * 是一个全局对象,但将其隐藏在一个函数中以供访问并没有什么错:
这里的缺点是MT真的应该通过调用
.discard( 1000 )
左右来“预热”...