2012-09-17 50 views
36

这是我的代码来生成使用种子作为参数的随机数。Java的随机数使用种子

double randomGenerator(long seed) { 
    Random generator = new Random(seed); 
    double num = generator.nextDouble() * (0.5); 

    return num; 
} 

每次我给一个种子并尝试生成100个数字,它们都是相同的。
请帮忙。

+3

这就是种子应该做的事情。你只为一个种子生成一个数字。你想达到什么目的? –

+0

可能的重复[Java随机总是返回相同的数字,当我设置种子?](http://stackoverflow.com/questions/5533191/java-random-always-returns-the-same-number-wheni-i- set-the-seed) – finnw

+2

您可以使用'System.currentTimeMillis()'作为种子来产生随机结果。不给任何种子也会产生随机结果。如果你不给予任何种子,我不知道它是否会在某个时候开始重复。 – WVrock

回答

60

如果您给出相同的种子,那很正常,那是一个允许测试的重要功能。

检查此理解伪随机数发生和种子:http://en.wikipedia.org/wiki/Pseudorandom_number_generator

的伪随机数发生器(PRNG),也被称为确定性 随机位产生DRBG,是用于生成数字的序列 的算法这近似于随机数的属性。所述 序列不是在于其完全 确定的相对小的组初始值真正随机的,被称为PRNG的状态, ,其包括真正的随机种子。

如果你想有不同的序列(通常情况下,当不调整或调试算法),你应该调用它使用nanoTime想尽一切时间来获得不同的种子零参数的构造函数。这个Random实例当然应该保存在你的方法之外。

你的代码也许应该是这样的:

private Random generator = new Random(); 
double randomGenerator() { 
     return generator.nextDouble()*0.5; 
} 
+0

毫秒是一个很长的时间,它会更安全使用System.nanoTime() – kukis

+0

@kukis这并不重要。这只是一个数字,在每个**节目**启动时都不一样。因为你的程序只设置一次种子。 –

+1

使用“new Random()”是等价的或更好的看到源:public Random(){ this(seedUniquifier()^ System.nanoTime()); } – dermoritz

6

这是一个伪 -RNG的原则。这些数字并不是真正的随机数。它们是使用确定性算法生成的,但取决于种子,生成的数字序列会有所不同。既然你总是使用相同的种子,你总是会得到相同的序列。

2

问题是,您再次种子随机发生器。每次种子时,随机数发生器的初始状态将被重置,并且您生成的第一个随机数将是初始状态后的第一个随机数

6

你不应该在方法的范围要创建一个新的随机。成为班级成员:

public class Foo { 
    private Random random 

    public Foo() { 
     this(System.currentTimeMillis()); 
    } 

    public Foo(long seed) { 
     this.random = new Random(seed); 
    } 

    public synchronized double getNext() { 
     return generator.nextDouble(); 
    } 
} 

这只是一个例子。我不认为包装Random这种方式增加了任何价值。把它放在你正在使用它的一类中。

+0

我把它放在我的主课堂上,并从那里调用它。 – WVrock

+0

这个答案几乎完全不相关的问题。 –

+3

它似乎没有关系,因为它似乎只是一个重构,但它是绝对相关的。每次调用方法时,OP都会重新实例化Random发生器,所以'nextDouble'将始终返回随机序列中的_first_ double。这个答案只实例化Random发生器一次,并且每次调用getNext'时,它实际上会遍历随机序列并每次返回一个不同的数字。 –

2

如果你想要使用一个种子,你可以做这样的事情来生成多个号码:

public double[] GenerateNumbers(long seed, int amount) { 
    double[] randomList = new double[amount]; 
    for (int i=0;i<amount;i++) { 
     Random generator = new Random(seed); 
     randomList[i] = Math.abs((double) (generator.nextLong() % 0.001) * 10000); 
     seed--; 
    } 
    return randomList; 
} 

如果使用相同的种子,它将显示相同的列表。

14

最简单的方法是使用:

Random rand = new Random(System.currentTimeMillis()); 

这是产生Random号的最好方法。

0

几个例子在这里创建一个新的Random实例,但是这是不必要的。作为解决方案,也没有理由使用​​。相反,请利用ThreadLocalRandom类别上的方法:

double randomGenerator() { 
    return ThreadLocalRandom.current().nextDouble(0.5); 
}