【问题标题】:What is random seed about?什么是随机种子?
【发布时间】:2014-06-01 09:15:07
【问题描述】:

例如下面的代码。它有一个随机类。然而,它总是在任何地方产生相同的输出。在这种情况下,哪个项目是种子?

来源:link

import java.util.Random;
public class RandomTest {
    public static void main(String[] s) {
        Random rnd1 = new Random(42);
        Random rnd2 = new Random(42);

        System.out.println(rnd1.nextInt(100)+" - "+rnd2.nextInt(100));
        System.out.println(rnd1.nextInt()+" - "+rnd2.nextInt());
        System.out.println(rnd1.nextDouble()+" - "+rnd2.nextDouble());
        System.out.println(rnd1.nextLong()+" - "+rnd2.nextLong());
    }
}

【问题讨论】:

  • 答案永远是42。下次先试试看javadoc吧。
  • @Klas Lindbäck 如果我能理解 javadoc,我不会在这里问。
  • 宇宙和一切的分析者都是42。这是个笑话。 random 函数使用种子创建令牌,如密码加密中的盐,但在那里添加非存储密钥。在这里,您可以使用相同的种子(id)来获得结果。
  • @WASasquatch 是否意味着在这种情况下每个密码都使用相同的盐值?
  • 通常他们使用随机盐,因为意图不是种子。它就像相反。在这里,我们打算重新使用种子,在那里他们只是加盐、调味,使其更难解密。所以他们会根据执行的第二个和日期使用微时间,即:.currentTimeMillis

标签: java random seed


【解决方案1】:

42 是种子,正如Javadoc 所说的。那么,什么是种子? random 数字很少是真正随机的 - 通常是 pseudo-random。这意味着它是从一个函数生成的,即 PRNG(伪随机数生成器)。反过来,从函数生成意味着输出不再是随机的,因为它是可预测的!

但是,根据您的需要,这种伪随机性可能就足够了 - 我说 足够了 因为生成随机位是昂贵的,而且我不是在谈论时间或记忆,但关于金钱(参见维基百科上的this link)。因此,例如,如果您需要一个随机值来在游戏中放置敌人,则可以使用伪随机数 - 但如果您正在构建与安全相关的软件,您希望使用真正的随机数,或者至少是一个 @ 987654323@.

我们如何描述一个 PRNG,就像 Math.random() 中使用的那个?它是一个函数,使用返回值数组 A 的 seed S 进行初始化。请注意,对于每个整数 S,定义一个且只有一个数组 A。例如(值不是实际值):

                first call     second call     third call
seed: 14329            .18             .82             .5
seed:  3989             .7             .02            .93

因此,当您希望其结果可预测时,您可以为 PRNG 播种一些已知值 - 例如出于测试目的或确保每次在游戏中运行级别 1 时,敌人总是被放置在相同的 (伪)随机位置 - 否则您不需要明确传递种子。

【讨论】:

    【解决方案2】:

    Random Seed on Wikipedia:

    随机种子(或种子状态,或只是种子)是一个数字(或向量) 用于初始化伪随机数生成器。

    换句话说,它是一个看似随机的序列将产生的数字。因此,如果您使用相同的数字,则序列将始终相同。

    在实践中,我们通常使用系统时间作为种子。

    【讨论】:

    • 除非您想要可重复的结果,否则您使用固定种子。
    • 这是真的,但我并没有真正看到它的实际用途是什么(测试除外)。生成固定序列?我会以另一种更可靠的方式下注。生成随机序列通常更注重性能。
    • 您希望在模拟中使用它们,这也是您在那里使用 PRNG 的主要原因(仅存储可重复结果的种子,而不是所需的所有随机数 :-))
    • @Јοеу 您还可以在模拟中使用它们来将一些花哨的技巧拉到reduce the variance 的估计模型特征。
    【解决方案3】:

    种子作为Random的构造函数的参数给出;使用相同的种子将产生相同的数字序列。但是,这在问题中的链接下进行了讨论。

    【讨论】:

      【解决方案4】:

      在这种情况下,种子是 42。这就是相同输出的原因 - 您使用相同的种子。 例如,您可以使用

        Random rnd1 = new Random(System.currentTimeMillis())
      

      针对不同的输出。

      【讨论】:

      • 他最好不要指定任何种子。使用System.currentTimeMillis() 很有可能为该方法的两次后续调用生成相同的种子。
      • @PS glass 正在使用 System,currentTimeMillis() 与 C++ 中的 srand(time()) 相同吗?
      • 我不太了解C++,但我认为是的。它非常相似,但我不确定。这个问题应该由懂两种语言(Java 和 C++)的人来回答。
      【解决方案5】:

      种子是伪随机数生成器内部状态的初始值,由方法 next(int) 维护。

      调用 new Random(seed) 等价于:

       Random rnd = new Random();
       rnd.setSeed(seed);
      

      【讨论】:

        【解决方案6】:

        来自Random class 中的 Java 文档

        使用单个长种子创建一个新的随机数生成器。种子是伪随机数生成器内部状态的初始值,由方法next(int)维护。

        调用 new Random(seed) 等价于:

        随机 rnd = new Random(); rnd.setSeed(种子);

        所以 42 是在您的示例中给 new Random() 的种子

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-04
          • 2019-11-12
          • 2014-05-19
          • 2013-02-01
          • 2020-09-13
          • 2022-12-17
          • 1970-01-01
          • 2022-07-11
          相关资源
          最近更新 更多