2011-10-26 98 views
17

我想在java中生成随机数,我知道我应该使用Math.random()这样的现有方法,但是,我的问题是:如何生成相同的数字序列,每次我运行我的应用程序? 例如:生成的顺序是:0.9,0.08,0.6 所以我想,这个序列将我每次执行该方法时产生..生成相同的随机数序列

回答

29

当然 - 只需创建的,而不是使用Math.random()Random一个实例,始终指定相同的种子:

Random random = new Random(10000); // Or whatever seed - maybe configurable 
int diceRoll = random.nextInt(6) + 1; // etc 

请注意,如果您的应用程序涉及多个线程,则会变得更难,因为时序变得难以预测。

这利用了Random是一个pseudo-random number generator - 换句话说,每次你问它一个新的结果,它操纵内部状态给你一个随机看看的序列,但知道种子(或实际上是当前的内部状态),这是完全可预测的。

+2

在线程的情况下,你可以给每个线程自己的随机(固定种子),或者如果你只使用一个预先填充的列表为每个从一个随机(具有固定的种子)。但是,如果线程彼此交互,这种方法不会再工作了。 – Stefan

6

您需要种子随机数发生器。

Random random = new Random(aFixedNumber); 
random.nextInt(); // will always be the same 
24

反复使用相同种子的示例。

public static void main(String... args) throws IOException { 
    printDoublesForSeed(1); 
    printDoublesForSeed(128); 
    printDoublesForSeed(1); 
    printDoublesForSeed(128); 
} 

private static void printDoublesForSeed(long seed) { 
    double[] doubles = new double[10]; 
    Random rand = new Random(seed); 
    for (int j = 0; j < doubles.length; j++) { 
     doubles[j] = (long) (rand.nextDouble() * 100)/100.0; 
    } 
    System.out.println("doubles with seed " + seed + " " + Arrays.toString(doubles)); 
} 

打印

doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93] 
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47] 
doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93] 
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47] 

编辑的随机种子的一个有趣的滥用。

public static void main(String ... args) { 
    System.out.println(randomString(-6225973)+' '+randomString(1598025)); 
} 

public static String randomString(int seed) { 
    Random rand = new Random(seed); 
    StringBuilder sb = new StringBuilder(); 
    for(int i=0;i<5;i++) 
     sb.append((char) ('a' + rand.nextInt(26))); 
    return sb.toString(); 
} 

打印

hello world 
+2

+1为了清楚地说明。 – mre

+2

我喜欢hello world的例子。我认为没有更好的解决方案,蛮力所有可能的种子找到正确的种子?编辑:显然不是,我不应该在得到我的第一杯咖啡之前写下东西:0 – Voo

+0

我刚用过蛮力。 ;) –

4

Math.random仅仅是一个类java.util.Random的包装。第一次调用Math.random时,会创建类java.util.Random的实例。

现在,大多数API不会公开任何true随机数发生器,因为它们不能在软件中实现。相反,他们使用伪随机数字发生器,它使用一组公式产生一系列随机数字。这是java.util.Random所做的。但是,每个伪随机数发生器首先需要接种。如果您有两个使用相同算法并使用相同种子的伪随机数生成器,它们将生成相同的输出。

默认情况下,java.util.Random使用1970年1月1日以来的毫秒作为种子。因此,每次启动程序时,它都会产生不同的数字(除非您管理它在1毫秒内启动java)。所以,解决问题的方法是自己创建自己的java.util.Random实例和种子它:

import java.util.Random; 

class ... { 
    Random randomNumberGenerator = new Random(199711); 

    public void ...() 
    { 
     int randomInt = randomNumberGenerator.nextInt(); 
     double randomDouble = randomNumberGenerator.nextDouble(); 
    } 
} 

randomNumberGenerator总是会吐出相同的数字序列,只要你不改变的种子( 199711)。

0

我会硬编码到应用程序的数字。这需要更多的内存,但速度要快得多。

只需将随机数打印到终端,然后将其复制粘贴到您的代码中。

一定要留下评论,解释你做了什么,否则他们会看起来像不知情的读者黑魔法。

相关问题