WiR*_*R3D 6 python java random scala mersenne-twister
我的任务是将一些 Python 代码移植到 Scala 以进行研究。现在我使用 Apache Math3 公共库并且在使用 MersenneTwister 时遇到了困难。
在 Python 中:
SEED = 1234567890
PRIMARY_RNG = random.Random()
PRIMARY_RNG.seed(SEED)
n = PRIMARY_RNG.randrange((2**31) - 1) #1977150888
Run Code Online (Sandbox Code Playgroud)
在斯卡拉:
val Seed = 1234567890
val PrimaryRNG = new MersenneTwister(Seed)
val n = PrimaryRNG.nextInt(Int.MaxValue) //1328851649
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么?两者都是 MersenneTwister 的,
并且Int.MaxValue = 2147483647 = (2**31) - 1
正如我已经在评论中发布的那样,获取下一个整数的主要算法在 Python 和 Apache Math 之间是相同的(源代码在这里、这里和这里)。跟踪代码似乎主要区别在于两个版本如何为生成器提供种子。Python 版本会将给定的种子转换为数组,并从数组中获取种子,而 Apache Math 版本则具有单独的算法,用于从单个数字进行种子播种。因此,为了让 Apache MathnextInt(...)方法以与 Python 方法一样的保存方式运行,randrange(...)您应该使用数组为 Apache Math 版本播种。
(我不懂Scala,所以下面的代码是Java的)
MersenneTwister rng = new MersenneTwister();
rng.setSeed(new int[] {1234567890});
System.out.println(rng.nextInt(Integer.MAX_VALUE)); // 1977150888
Run Code Online (Sandbox Code Playgroud)
另请注意,所有其他方法(例如random()vs.)nextDouble()都完全不同,因此这种播种机制可能只能产生nextInt(...)并randrange(...)返回相同的结果。