背景
搞科研时候,一部分数据在python中生成的,但是我们做对比实验,需要保证数据前后一致,所以Java中也需要生成相同的数据。
发现问题
然后分别使用简单的代码测试了一下,这里规定了相同的随机数种子。
@Test
public void randomTest() {
Random random = new Random(3);
for (int i = 0; i < 10; i++) {
System.out.println(random.nextDouble());
}
}
import random as rd
rd.seed(3)
for _ in range(10):
print(rd.random())
结果发现两个生成的序列不一致
问题解决
在网上找了找资料发现!
Python 和 Java 中使用相同的随机种子生成随机数,通常不会得到相同的结果。主要原因如下:
-
随机数生成算法不同:Python 的随机数生成器基于 Mersenne Twister 算法。Java 的随机数生成器使用的是 Linear Congruential Generator (LCG) 算法。即使在相同的随机种子下,由于两种语言使用的算法不同,生成的随机数序列也会有所不同。
-
实现细节不同: 每种语言对随机数生成器的实现细节(如初始状态和数值范围)可能会有所不同,这也会导致同样的种子生成的随机序列不同。
这里我们使用一种解决方案:使用 NumPy 和 Java 配合
- 考虑在 Python 中使用 NumPy 的 Mersenne Twister。
- 在Java中使用 Apache Commons Math 库: 你可以引入 Apache Commons Math,它包含 MersenneTwister 类。
在python中这样定义,每次调用rd.random()
方法
import numpy as np
rd = np.random
rd.seed(3)
for i in range(10):
print(rd.random())
Java中这样定义,每次调用random.nextDouble()
方法,如果需要整数,先求得double数值后,再自行处理得到整数对象
MersenneTwister random = new MersenneTwister(3);
for (int i = 0; i < 10; i++) {
System.out.println(random.nextDouble());
}
这样得到的结果是匹配的