随机生成器每次都给我相同的数字

4
import java.util.Random;

public class Fighter {
int str;
int dex;
int hth;
Random gen = new Random(1535636);   

public Fighter() {
     str = gen.nextInt(9);
     dex = gen.nextInt(9);
     hth = gen.nextInt(14);
}


public int getHth(){

   return hth;

   }

public int getStr(){
   return str;
   }

public int getDex(){
   return dex;
       }
 }


import java.util.Random;
public class Arena {


public static void main(String[] args) {
    Random gen = new Random();
      Fighter Guy1 = new Fighter();
      int x =1;
              while (x < 200000000){
                x++;  
              }
      Fighter Guy2 = new Fighter();

    int hth1 = Guy1.getHth();
    int hth2 = Guy2.getHth();

    System.out.println("Fight Start");
    System.out.println("---------------");
    //System.out.println(gen.nextInt(10));
    //System.out.println(gen.nextInt(17));
    System.out.println(Guy1.getStr());

    //Fighting



}



}

每次运行此代码,无论如何都会得到相同的结果。我希望每次生成两个随机的战士。目前有几行代码只是为了确认它不会生成随机数。
有人知道如何正确地在构造函数中使用随机数吗?还是我完全错了?
2个回答

13

您正在为随机数生成器提供一个恒定的种子值:

Random gen = new Random(1535636);  

不要这样做。它总是提供相同的值。只需调用默认构造函数:

Random gen = new Random();

创建一个新的随机数生成器。它的种子被初始化为基于当前时间的一个值:

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#Random()


为什么?

和大多数“标准库”随机数生成器一样,Random是一个“伪随机数生成器”。这意味着它并没有真正地生成随机数!相反,它以非常明确定义的方式计算它们——它们只是看起来像随机数,而且它们往往有一个不错的分布。

PRNGs使用一个种子值进行初始化,该值设置它们的内部状态。如果您每次提供相同的种子值,则 PRNG 每次运行时都会处于相同的状态,从而提供相同的数字序列!

使它们似乎始终随机的事情通常1是它们默认使用基于时间的值进行“种子化”。在大多数库中,这是一个具有非常好精度的时间派生值。因此,大多数情况下,如果您看到有人对他们的 PRNG 进行种子化,那么这可能是不正确的,或者至少是非常不必要的。

1 - 注意:这不适用于来自libc的rand()函数:“如果没有提供种子值,则rand()函数会自动使用值1进行种子化。”


谢谢,我以为种子会与当前时间一起使用。 - tekno45

4

现在你正在使用相同的种子初始化随机数生成器。这将使它每次都产生相同的数字序列。你应该使用无参构造函数

Random gen = new Random();

根据文档
构造函数将随机数生成器的种子设置为一个非常有可能与该构造函数的任何其他调用不同的值。

哦,好的,我以为种子会与当前时间一起使用。 - tekno45

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接