在单元测试中使用 std::mt19937(带有固定种子)是否安全?

Is it safe to use std::mt19937 (with fixed seed) within unit tests?

提问人:Gael Lorieul 提问时间:11/2/2023 更新时间:11/2/2023 访问量:85

问:

我编写了一个需要随机数生成器 (RNG) 的函数的单元测试。测试函数的实现从以下行开始:

const int nSeed = 0;
std::mt19937 randNbGen(nSeed);

randNbGen 对象稍后在同一函数中用于执行最终生成其返回值的计算。

通过播种 RNG,它会从一次运行到下一次运行生成相同的数字序列,我需要这些序列才能使单元测试保持一致。此外,我假设通过使用 std 库中的 RNG(在我的情况下为 std::mt19937),我可以保证生成的数字序列将来不会改变。

但是:6 个月后(即现在)测试失败。我检查了以前通过测试的提交,现在它以与当前相同的函数输出未通过测试。我还注意到 randNbGen 在两次提交中生成相同的数字序列。

RNG(实现)确实有可能改变吗?还是我一定是在某个地方偷偷摸摸的?
处理这种情况的推荐方法是什么?
奖励问题:RNG 的行为在各个平台上是恒定的吗?

PS:我在 Windows 上使用 MSVC (Visual Studio 2022)

C++ 单元测试 随机种子

评论

4赞 François Andrieux 11/2/2023
生成器引用了 Mersenne Twister 的特定版本:32 位 Mersenne Twister by Matsumoto and Nishimura, 1998 在我看来,他们不太可能有意义地改变它。std::mt19937
2赞 Pepijn Kramer 11/2/2023
它并非不安全,但它只会一遍又一遍地生成相同的随机数序列,假设您不使用分布(分布将自己的状态添加到生成的输出中,并且允许更改))。我认为失败的测试会让我更担心......如果我使用随机生成器,我希望无论输入如何,我的所有测试都能继续成功。(查找模糊测试)
3赞 Fareanor 11/2/2023
“测试失败”是什么意思?是什么让你认为问题来自RNG?也许您的代码在其他地方有问题,或者有未定义的行为,或者......如果不知道哪些代码失败了,你期望什么,以及你得到了什么,我们就无法知道。
2赞 Pete Becker 11/2/2023
标准库中的随机数生成器使用完全指定的算法(包括对生成的第 1000 个值的要求,这在实现它们时很方便)。如果您的测试现在失败,那不是 RNG 的错。
2赞 Alan Birtles 11/3/2023
请注意,随机库的其他部分没有那么严格,例如,如果您使用的是分布,它们可能会随着新的标准库版本而更改

答: 暂无答案