首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java Math3 MersenneTwister与Python随机

Java Math3 MersenneTwister与Python随机
EN

Stack Overflow用户
提问于 2014-08-04 20:29:26
回答 3查看 657关注 0票数 6

为了研究目的,我的任务是将一些python代码移植到Scala。现在我使用,并且在使用Math3时遇到了困难。

在Python中:

代码语言:javascript
复制
SEED = 1234567890

PRIMARY_RNG = random.Random()
PRIMARY_RNG.seed(SEED)
n = PRIMARY_RNG.randrange((2**31) - 1) #1977150888

在Scala中:

代码语言:javascript
复制
val Seed = 1234567890
val PrimaryRNG = new MersenneTwister(Seed)
val n = PrimaryRNG.nextInt(Int.MaxValue) //1328851649

我在这里错过了什么?都是MersenneTwister的

Int.MaxValue = 2147483647 = (2**31) - 1

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-05 13:18:19

正如我在评论中已经发布的,获取下一个整数的主要算法在Python和Apache (源代码这里这里这里)之间是相同的。通过代码进行跟踪,似乎主要的区别在于这两个版本如何启动生成器。Python版本将将给定的种子转换为数组和数组中的种子,而Apache版本则有一个单独的算法,用于从单个数字中播种。因此,为了使Apache nextInt(...)方法以保存方式作为Python方法,您应该使用一个数组为Apache版本添加种子。

(我不知道Scala,所以下面的代码是用Java编写的)

代码语言:javascript
复制
MersenneTwister rng = new MersenneTwister();
rng.setSeed(new int[] {1234567890});
System.out.println(rng.nextInt(Integer.MAX_VALUE)); // 1977150888

还要注意的是,所有其他方法(如random()nextDouble() )都完全不同,因此这种种子机制很可能只用于使nextInt(...)randrange(...)返回相同的结果。

票数 2
EN

Stack Overflow用户

发布于 2014-08-04 21:10:00

Apache显然是使用整数作为随机性的基本来源。的,尽管我不太确定它是如何提取的,而Python则是使用算法的C版本生成的double

种子值的处理方式也可能有差异,但由于它们甚至没有以相同的方式读出比特,所以即使潜在的伪随机生成器是相同的,也不会期望它们具有可比性。

票数 3
EN

Stack Overflow用户

发布于 2019-01-11 06:21:22

如果有人需要这样做,我想出了一个基于这里的CPython实现的工作版本。

注意:如果使用字符串作为种子,则random.seed()在Python2和3之间更改。这里的pythonStringHash函数与Python2版本或Python3中的random.seed(s, version=1)兼容。

代码语言:javascript
复制
private static long pythonStringHash(String s) {
  char[] chars = s.toCharArray();
  long x;
  if (s.isEmpty()) {
    x = 0;
  } else {
    x = chars[0] << 7;
  }

  for (char c : chars) {
    x = ((1000003 * x) ^ c);
  }

  x ^= chars.length;
  if (x == -1) {
    return -2;
  }
  return x;
}

private static void pythonSeed(MersenneTwister random, long seed) {
  int[] intArray;
  if (Long.numberOfLeadingZeros(seed) >= 32) {
    intArray = new int[] { (int) seed };
  } else {
    intArray = new int[] { (int) seed, (int) (seed >> 32) };
  }
  random.setSeed(intArray);
}

public static RandomGenerator pythonSeededRandom(String seed) {
  MersenneTwister random = new MersenneTwister();
  pythonSeed(random, pythonStringHash(seed));
  return random;
}

从那里开始,pythonSeededRandom("foo").nextDouble()应该等于random.seed("foo"); random.random()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25127021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档