C++ 如果我们播下c++;11 mt19937在不同的机器上相同,我们会得到相同的随机数序列吗

C++ 如果我们播下c++;11 mt19937在不同的机器上相同,我们会得到相同的随机数序列吗,c++,c++11,random,C++,C++11,Random,受和类似问题的启发,我想学习C++11中的mt19937伪数生成器在两台不同的机器中使用相同的输入进行播种时的行为 换句话说,假设我们有以下代码 std::mt19937 gen{ourSeed}; std::uniform_int_distribution<int> dest{0, 10000}; int randNumber = dist(gen); std::mt19937 gen{ourSeed}; std::均匀分布dest{0,10000}; int randNumbe

受和类似问题的启发,我想学习C++11中的mt19937伪数生成器在两台不同的机器中使用相同的输入进行播种时的行为

换句话说,假设我们有以下代码

std::mt19937 gen{ourSeed};
std::uniform_int_distribution<int> dest{0, 10000};
int randNumber = dist(gen);
std::mt19937 gen{ourSeed};
std::均匀分布dest{0,10000};
int randNumber=dist(gen);
如果我们在不同的时间在不同的机器上尝试这段代码,我们每次会得到相同的randNumber值序列还是不同的序列

在这两种情况下,为什么会出现这种情况

还有一个问题:


不管种子是什么,这个代码会无限地随机生成数字吗?我的意思是,例如,如果我们在一个运行数月而不停止的程序中使用这段代码,那么在生成数字或数字的一致性方面会有任何问题吗?

任何接受种子的伪RNG都会在每台机器上每次为同一种子提供相同的序列。之所以会发生这种情况,是因为生成器只是一个(复杂的)数学函数,实际上没有任何随机性。大多数时候,当你想随机化时,你从系统时钟中获取种子,它会不断变化,因此每次运行都会不同。
在电脑游戏中使用相同的序列是很有用的,例如,当你有一个随机生成的世界并且想要生成完全相同的世界时,或者为了避免人们在随机机会的游戏中使用保存游戏作弊。

生成器将生成相同的值

发行版可能不会,至少对于不同的编译器或库版本。该标准没有详细说明他们的行为。如果您想要编译器和库版本之间的稳定性,就必须推出自己的发行版

禁止库/编译器更改,这将以相同的顺序返回相同的值。但是如果你愿意的话,写下你自己的发行版

所有PRNG都有模式和周期。以其2^19937-1时期命名,这不太可能是个问题。但也可以发展其他模式。MT-prng对许多统计测试都是稳健的,但它们在晶体上不是安全的prng

所以,如果你跑了几个月,这将取决于你发现问题的具体细节。然而,mt19937将是一个更好的PRNG比任何你可能写自己。但假设攻击者可以根据过去的证据预测其未来行为

不管种子是什么,这个代码会无限地随机生成数字吗?我的意思是,例如,如果我们在一个运行数月而不停止的程序中使用这段代码,那么在生成数字或数字的一致性方面会有任何问题吗

我们用标准C++处理RNG,称为伪随机RNG。根据定义,这是纯计算设备,具有多位状态(您可以将状态视为大位向量)和三个功能:

  • 国家种子2国家(种子)
  • 州下一个州(州)
  • uint(32 | 64)状态2输出(状态)
就这样。显然,状态的大小是有限的,在MT19937的情况下是19937位,因此状态的总数是219937,因此MT19937 next_state()函数是周期函数,最大周期不超过219937。这个数字真的很大,很可能对于典型的模拟来说已经足够了

但输出最大为64位,因此输出空间为264。这意味着在大型运行期间,任何特定的输出都会出现很多次。重要的是,不只是64位的数字再次出现,还有之后的数字,以及之后的数字——这就是你们知道RNG周期已经到了的时候

如果我们在不同的时间在不同的机器上尝试这段代码,我们每次会得到相同的randNumber值序列还是不同的序列

生成器的定义相当严格,您将得到相同的位流。例如,从C++标准(MT/37)到MT1937 函数seed2state描述为()

效果:构造一个mersenne扭曲引擎对象。集合X−n到值mod 2w。然后,迭代地为我=−n、 ,…,−1,设席至……/P> 函数next_状态也将与第10000次调用时的测试值一起描述。标准说()

使用mt19937=mersenne_捻线机_发动机;
3.
#必需行为:默认构造对象的第10000次连续调用
mt19937型应产生值4123659995。
我使用的四大编译器(GCC、Clang、VC++、Intel C++)产生了相同的MT19937输出


另一方面,发行版并没有被很好地指定,因此在编译器和库之间有所不同。如果你需要便携式发行版,你可以自己翻转,或者使用Boost或类似的库

Irc中的某个东西,C++标准没有指定“<代码> MistalIn ItIn发行< <代码> >必须从熵源产生随机值的算法。我不明白你的意思。不能保证你会得到相同的序列号。但是,直接调用
gen()
可以得到相同的数字序列。Mersenne Twister算法在给定种子的情况下是完全确定的。您应该指定“在不同的机器上”的确切含义。一个内置的可执行文件,还是同一个源被编译成一个?@ StyyToelt同时考虑这两个问题。但是C++标准没有指定<代码> MistalIn ItIsPalth<<代码>…@ @ OLIVARCHARESVISH的功能,只要运行编译版本,就不重要了。如果你在不同的机器上使用不同的编译器进行编译,这才有意义。我想,还不完全清楚OP所说的“在不同的机器上尝试这段代码”是什么意思——他们在说什么
class mersenne_twister_engine {
...
static constexpr result_type default_seed = 5489u;
...
using mt19937 = mersenne_twister_engine<uint_fast32_t,32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>;


3
#Required behavior: The 10000th consecutive invocation of a default-constructed object
of type mt19937 shall produce the value 4123659995.