【问题标题】:Java random numbers using a seed使用种子的 Java 随机数
【发布时间】:2012-09-09 14:49:21
【问题描述】:

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

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

    return num;
}

每次我给一个种子并尝试生成 100 个数字时,它们都是相同的。
我该如何解决这个问题?

【问题讨论】:

  • 这就是种子应该做的事情。您只为种子生成一个数字。你想达到什么目的?
  • 您可以使用System.currentTimeMillis() 作为种子来产生随机结果。不提供任何种子也会产生随机结果。如果您不提供任何种子,我不确定它是否会在某个时候开始重复。

标签: java random seed


【解决方案1】:

如果您提供相同的种子,那是正常的。这是允许测试的重要功能。

检查这个以了解伪随机生成和种子:

Pseudorandom number generator

伪随机数生成器 (PRNG),也称为确定性 随机位发生器 DRBG,是一种生成序列的算法 近似随机数的性质的数字。这 序列并不是真正随机的,因为它完全由 一组相对较小的初始值,称为 PRNG 的状态, 其中包括一个真正随机的种子。

如果你想有不同的序列(不调整或调试算法时的常见情况),你应该调用零参数构造函数,它使用 nanoTime 尝试每次获取不同的种子。这个Random 实例当然应该保留在您的方法之外。

你的代码应该是这样的:

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

【讨论】:

  • 毫秒是很长的时间,使用 System.nanoTime() 会更安全
  • @kukis 没关系。这只是一个在每次 program 启动时都不相同的数字。因为你的程序只设置一次种子。
  • 使用“new Random()”是等价的或者更好看来源:public Random() { this(seedUniquifier() ^ System.nanoTime()); }
  • 假设我已经在课堂上定义了 new Random(42) 并且在另一个课堂上我再次只做 new Random() 并且我得到了不同的结果...有什么技术可以设置随机种子在全局范围内,对于每个类,即使我初始化 new Random(),我也会为每个类获得相同的值。如果有人能回答会很有帮助。
  • @GauravKoradiya 这通常是一个问题,并且明显违反了设计原则。所以不,没有办法。您可以将种子或 Random 实例传递到需要它的位置。
【解决方案2】:

简单的方法是使用:

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

这是生成Random 号码的最佳方式。

【讨论】:

  • 在特殊情况下,当您的代码运行速度过快时,可以从相同的种子开始
【解决方案3】:

您不应该在方法范围内创建新的 Random。使其成为类成员:

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 会增加任何价值。把它放在你正在使用它的班级中。

【讨论】:

  • 这个答案与问题几乎完全无关。
  • 它可能看起来不相关,因为它似乎只是一个重构,但它肯定是相关的。每次调用该方法时,OP 都会重新实例化 Random 生成器,因此 nextDouble 将始终返回随机序列中的 first 双精度值。此答案仅将 Random 生成器实例化一次,每次调用 getNext 它实际上会逐步遍历随机序列并每次返回不同的数字。
【解决方案4】:

这就是-RNG的原理。这些数字并不是真正随机的。它们是使用确定性算法生成的,但根据种子的不同,生成数字的顺序会有所不同。因为你总是使用相同的种子,所以你总是得到相同的序列。

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

      如果您想使用一个种子生成多个数字,您可以执行以下操作:

      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;
      }
      

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

      【讨论】:

        【解决方案7】:

        这里的几个示例创建了一个新的Random 实例,但这是不必要的。也没有理由像一种解决方案那样使用synchronized。相反,请利用 ThreadLocalRandom 类的方法:

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

        【讨论】:

          猜你喜欢
          • 2016-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-04
          • 2013-05-28
          相关资源
          最近更新 更多