【问题标题】:Default seed PRNG in JavaJava中的默认种子PRNG
【发布时间】:2013-11-19 00:20:19
【问题描述】:

我想知道 Java 中 Math.random() 后面的 PRNG* 的默认种子是什么。据我了解,C 中的一个是基于系统时钟的。那么它在Java中是否相似?另外,每次调用Math.random() 时,种子是否都会改变?

*PRNG = 伪随机数生成器

【问题讨论】:

    标签: java random prng


    【解决方案1】:

    如果你Read The Fine Manual 它会告诉你

    当这个方法第一次被调用时,它会创建一个新的 伪随机数生成器,就好像通过表达式

    new java.util.Random()

    使用了这个新的伪随机数生成器 此后用于对该方法的所有调用,并且不会在其他任何地方使用。

    跟进java.util.Random(),文档说

    public Random()

    创建一个新的随机数生成器。此构造函数设置种子 随机数生成器的值很可能是不同的 从此构造函数的任何其他调用。

    当前的实现似乎基于System.nanoTime(),但可能会发生变化,但仍符合文档合同。

    至于每次调用都更改种子,这不是种子的工作方式。 PRNG 被播种一次,然后产生从该初始状态演变而来的一系列值。您不应该,Java 也不会,继续重新播种。

    【讨论】:

    • 如果我们使用类似rand.setSeed(System.currentTimeMillis( ));的东西表示这个语句使用当前时间作为种子,那么如果当前时间是20:01,那么种子或起始值将是20还是01?还是 2001 年?
    • @AHF Javadocs 是你的朋友。
    【解决方案2】:

    您可以随时阅读code

    Math.random() 只使用一个内部静态随机对象,该对象实例化时没有参数...

           Random() {
    90         this(seedUniquifier() ^ System.nanoTime());
    91     }
    92 
    93     private static long seedUniquifier() {
    94         // L'Ecuyer, "Tables of Linear Congruential Generators of
    95         // Different Sizes and Good Lattice Structure", 1999
    96         for (;;) {
    97             long current = seedUniquifier.get();
    98             long next = current * 181783497276652981L;
    99             if (seedUniquifier.compareAndSet(current, next))
    100                return next;
    101        }
    102    }
    103
    104    private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
    

    【讨论】:

      【解决方案3】:

      正如您在 documentation 上看到的那样,该函数使用一个名为 Random() 的类,它使用 48 位种子,并生成均匀分布。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-03
        • 2014-09-16
        • 2021-11-10
        相关资源
        最近更新 更多