如果我在java程序中对Random使用相同的种子值并在两台不同的机器上运行它,我会得到相同的数字集吗?
例如
long seed = 123L;//may be taken from some database or something
java.util.Random ran = new java.util.Random(seed);
int ret = 0;
for (int i= 0; i< 10; i++){
ret = ran.nextInt(1000);
System.out.println("ret="+ret);
}
我总是得到
ret=782
ret=450
ret=176
ret=789
ret=795
ret=657
ret=834
ret=837
ret=585
ret=453
如果我在我的电脑上多次运行,我会得到相同的数字集......但是假设有人设法获得我使用的秘密种子值(通过猜测或来自秘密位置)存储的地方)并在他的机器上运行此代码,他会得到相同的数字集吗?
答案 0 :(得分:8)
是的,指定生成随机数的方式的合同在两种情况下都是相同的,因此如果给出相同的种子,它们将产生相同的数字序列。 Random
的实现必须使用规定的算法,以确保这种情况。一个更精确的方式(来自相关文档)是:
如果使用相同的种子创建了两个Random实例,那么 为每个方法调用相同的方法调用,它们将生成和 返回相同的数字序列。为了保证这一点 属性,为Random类指定特定算法。 Java实现必须使用此处显示的所有算法 class Random,为了Java代码的绝对可移植性。 但是,Random类的子类允许使用other 算法,只要它们遵守所有人的一般合同 方法。
答案 1 :(得分:2)
是的,这就是重点。
例如:在Minecraft中,您可以获取级别种子来初始化随机生成器,并且拥有此种子的每个人都将获得相同的地图。
如果您阅读the JavaDoc,则会看到next(int bits)
(而nextInt()
只是next(32)
)会将种子更新为(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
并返回{ {1}}。对于同一种子,这在任何计算机上都是一样的。
答案 2 :(得分:2)
JRE应生成相同的随机数序列,因为它们使用相同的种子,并使用算法。 Random上的Java文档说:
如果使用相同的种子创建了两个Random实例,并且为每个实例创建了相同的方法调用序列,则它们将生成并返回相同的数字序列。
所有JRE实现都使用这些算法:
为了保证此属性,为Random类指定了特定的算法。为了Java代码的绝对可移植性,Java实现必须使用此处显示的所有算法用于Random类。但是,Random类的子类允许使用其他算法,只要它们遵守所有方法的一般合同即可。
答案 3 :(得分:1)
答案是肯定的,因为Random.nextInt()的方式受到了影响。它只是使用种子并进行一些计算来生成数字。该代码不使用任何mahcine特定参数代。这是nextInt()的代码:
public int nextInt(int n) {
if (n<=0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while(bits - val + (n-1) < 0);
return val;
}
在此处阅读有关Random nextInt方法的更多信息:
http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#nextInt(int)