C++ PRNG MTRand mt.seed()未按预期工作(?)
在一个模拟项目中,我需要使用具有公共随机数(可复制性)的不同PRNG,我使用Jasper Bedaux()的Mersene Twister实现。现在,根据我的理解,下面的循环应该产生一个与整数相关联的唯一随机数(即,如果使用相同的种子初始化,不同的实例应该产生相同的随机数):C++ PRNG MTRand mt.seed()未按预期工作(?),c++,random,C++,Random,在一个模拟项目中,我需要使用具有公共随机数(可复制性)的不同PRNG,我使用Jasper Bedaux()的Mersene Twister实现。现在,根据我的理解,下面的循环应该产生一个与整数相关联的唯一随机数(即,如果使用相同的种子初始化,不同的实例应该产生相同的随机数): #包括 #包括“mtrand.cpp” int main() { MTRand测试仪; MTRand测试仪; std::cout这是因为一些奇怪的原因,MTRand的状态是static,因此状态在MTRand实例之间共享。
#包括
#包括“mtrand.cpp”
int main()
{
MTRand测试仪;
MTRand测试仪;
std::cout这是因为一些奇怪的原因,MTRand
的状态是static
,因此状态在MTRand
实例之间共享。这是一个非常糟糕的决定
也许你可以通过使状态非静态来解决这个问题。或者只是使用更好的MT实现(顺便说一句,C++11有std::mersenne\u twister\u engine
)这是因为一些奇怪的原因,MTRand
的状态是static
,所以状态在MTRand
实例之间共享。这是一个非常糟糕的决定
也许你可以通过使状态非静态来解决这个问题。或者只是使用更好的MT实现(顺便说一句,C++11有std::mersenne_twister_engine
)实际上,mersenne twister状态向量在这个端口是静态的,因为它在许多实现中都是静态的,包括最初的at实现
这不是出于“奇怪的原因”,这是否是一个“非常糟糕的决定”有待讨论
<>在C++标准实现中,它不是静态的,其缺点是很容易(偶然)如果您在某个类中构造一个新的MT引擎,请创建多个状态向量。每次构造一个新的MT引擎时,都会初始化一个新的状态向量并对其进行种子设定。大多数程序员可能不会意识到这一点,可能会忘记对每个新实例进行正确的种子设定,这可能会导致伪随机数的质量问题关于默认种子(重复序列的机会)的实现,请参见例如。
在正常情况下,您应该只使用一个发电机引擎,但问题是程序员可能没有意识到这一点。
从一个正确播种和使用的MT状态向量中获取下一个数字可能总是比初始化和播种一个单独的状态向量(这也是昂贵的)更好。这就是选择一个静态(集中式)状态向量的原因:保护用户不意外地创建多个状态向量。
但是,我同意,这不是一个好的解决方案,当您试图故意创建两个单独的状态向量时,这会造成混乱,顺便说一句,这只在非常特定的情况下有用,比如研究引擎的行为。当您只寻找高质量的随机数时,使用多个状态向量可能只会有害r
哪种解决方案最好取决于您试图完成的任务以及程序员对RNG实现的理解程度
不管怎样,台词
tester_sh.seed( sh );
tester_se.seed( se );
在本例中,此实现与
tester_se.seed( se );
编辑:正如geza和Sebastian在下面的评论中指出的那样,类的设计方式不是一个好的选择,因为它不反映内部工作。事实上,Mersenne Twister状态向量在这个端口是静态的,因为它在许多实现中都是静态的,包括最初的在
这不是出于“奇怪的原因”,这是否是一个“非常糟糕的决定”有待讨论
<>在C++标准实现中,它不是静态的,其缺点是很容易(偶然)如果您在某个类中构造一个新的MT引擎,请创建多个状态向量。每次构造一个新的MT引擎时,都会初始化一个新的状态向量并对其进行种子设定。大多数程序员可能不会意识到这一点,可能会忘记对每个新实例进行正确的种子设定,这可能会导致伪随机数的质量问题关于默认种子(重复序列的机会)的实现,请参见例如。
在正常情况下,您应该只使用一个发电机引擎,但问题是程序员可能没有意识到这一点。
从一个正确播种和使用的MT状态向量中获取下一个数字可能总是比初始化和播种一个单独的状态向量(这也是昂贵的)更好。这就是选择一个静态(集中式)状态向量的原因:保护用户不意外地创建多个状态向量。
但是,我同意,这不是一个好的解决方案,当您试图故意创建两个单独的状态向量时,这会造成混乱,顺便说一句,这只在非常特定的情况下有用,比如研究引擎的行为。当您只寻找高质量的随机数时,使用多个状态向量可能只会有害r
哪种解决方案最好取决于您试图完成的任务以及程序员对RNG实现的理解程度
不管怎样,台词
tester_sh.seed( sh );
tester_se.seed( se );
在本例中,此实现与
tester_se.seed( se );
编辑:正如geza和Sebastian在下面的评论中指出的那样,类的设计方式不是一个好的选择,因为它没有反映内部工作。只是出于好奇,但是为什么不使用标准库中实现的一个:?嗨,谢谢。我正在使用一个名为ABMs的IDE,它最近才开始使用c++11/14.我将检查c++11 MT是否与Bedaux实现一样易于使用(过去是/应该是…).不过,这个问题对我来说还是很神奇,我很想理解它。大多数时候,类似的问题有时会在以后困扰我…只是出于好奇,但你为什么不使用标准库中实现的一个:?嗨,谢谢。我正在使用一个名为ABMs的IDE,它最近才开始使用c++11/14。我将检查c++11 MT是否它与Bedaux实现(过去/应该是…)一样易于使用。不过,这个问题对我和