我想在 C++ 中复制一些已经在 Python3 中实现的代码的测试,这些代码依赖于 numpy.random.rand
和 randn
值和特定种子(例如, seed = 1
)。
我知道 Python 的随机实现基于梅森扭曲器。 C++ 标准库也在 std::mersenne_twister_engine
中提供了这一点。 .
C++ 版本返回一个 unsigned int,而 Python rand 是一个浮点值。
有没有办法在 C++ 中获得与在 Python 中生成的相同的值,并确保它们相同?由 randn
生成的数组也是如此?
最佳答案
对于整数值,您可以这样做:
import numpy as np
np.random.seed(12345)
print(np.random.randint(256**4, dtype='<u4', size=1)[0])
#include <iostream>
#include <random>
int main()
{
std::mt19937 e2(12345);
std::cout << e2() << std::endl;
}
两个片段的结果都是 3992670690通过查看 source code的
rand
您可以通过以下方式在 C++ 代码中实现它:import numpy as np
np.random.seed(12345)
print(np.random.rand())
#include <iostream>
#include <iomanip>
#include <random>
int main()
{
std::mt19937 e2(12345);
int a = e2() >> 5;
int b = e2() >> 6;
double value = (a * 67108864.0 + b) / 9007199254740992.0;
std::cout << std::fixed << std::setprecision(16) << value << std::endl;
}
两个随机值都是 0.9296160928171479使用会很方便
std::generate_canonical
,但它使用另一种方法将梅森扭曲器的输出转换为双倍。他们不同的原因很可能是generate_canonical
比 NumPy 中使用的随机生成器更优化,因为它避免了代价高昂的浮点运算,尤其是乘法和除法,如 source code 所示.然而,它似乎取决于实现,而 NumPy 在所有平台上产生相同的结果。double value = std::generate_canonical<double, std::numeric_limits<double>::digits>(e2);
这不起作用并产生结果 0.8901547132827379,这与 Python 代码的输出不同。
关于python - 与 Python3 numpy.random.rand 计算的 C++ 中相同的随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65871948/