【问题标题】:random number with seed带种子的随机数
【发布时间】:2011-04-04 18:05:34
【问题描述】:

参考:link text

下面这行我看不懂,谁能给我举个例子来说明下面的语句?

如果使用相同的种子创建 Random 的两个实例,并且为每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列

【问题讨论】:

  • 遵循该声明非常简单。 Random r1, r2,使用相同的种子创建和初始化(参见文档)。每次拨打next 5 次。它们将返回完全相同的 5 个“随机”数字序列。

标签: java


【解决方案1】:

既然你问了一个例子:

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

两个Random 实例将始终具有相同的输出,无论您运行它的频率如何,无论您使用什么平台或Java 版本:

30 - 30
234785527 - 234785527
0.6832234717598454 - 0.6832234717598454
5694868678511409995 - 5694868678511409995

【讨论】:

    【解决方案2】:

    随机生成器是确定性的。给定 Random 的相同输入和 Random 中方法的相同用法,即使在不同机器上的不同运行中,返回给您的程序的伪随机数序列也是相同的。

    这就是为什么它是伪随机的 - 返回的数字 表现 在统计上类似于随机数字,但它们可以可靠地预测。真正的随机数是不可预测的。

    【讨论】:

      【解决方案3】:

      Random 类基本上是一个伪随机数生成器(也称为确定性随机位生成器),它生成近似随机数属性的数字序列。它通常不是随机的,而是确定性的,因为它可以由生成器中的小随机状态(例如seed)确定。由于确定性,如果您的方法序列和种子在 2 个生成器上相同,则可以生成相同的结果。

      【讨论】:

        【解决方案4】:

        数字并不是真正随机的,给定相同的起始条件(种子)和相同的操作序列,将生成相同的数字序列。这就是为什么将基本 Random 类用作任何密码学或安全相关代码的一部分并不是一个好方法,因为攻击者可能会找出正在生成的序列并预测未来的数字。

        对于发出不确定值的随机数生成器,请查看SecureRandom

        有关更多信息,请参阅维基百科上的 Random number generation, Computational methods

        【讨论】:

          【解决方案5】:

          这意味着当您创建 Random 对象时(例如在程序开始时),您可能希望从一个新种子开始。大多数人选择一些与时间相关的值,例如滴答数。

          如果你想调试你的程序,数字序列相同的事实实际上非常方便:确保记录种子值,如果出现问题,你可以使用它在调试器中重新启动程序相同的种子值。这意味着您可以准确地回放场景。如果您(可以)使用真正的随机数生成器,这将是不可能的。

          【讨论】:

            【解决方案6】:

            使用相同的种子值,Random 的不同实例将返回/生成相同的随机数序列;更多关于这里: http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Tech/Chapter04/javaRandNums.html

            Ruby 示例:

            class LCG; def initialize(seed=Time.now.to_i, a=2416, b=374441, m=1771075); @x, @a, @b, @m = seed % m, a, b, m; end; def next(); @x = (@a * @x + @b) % @m; end; end
            
            irb(main):004:0> time = Time.now.to_i
            => 1282908389
            
            irb(main):005:0> r = LCG.new(time)
            => #<LCG:0x0000010094f578 @x=650089, @a=2416, @b=374441, @m=1771075>
            irb(main):006:0> r.next
            => 45940
            irb(main):007:0> r.next
            => 1558831
            irb(main):008:0> r.next
            => 1204687
            irb(main):009:0> f = LCG.new(time)
            => #<LCG:0x0000010084cb28 @x=650089, @a=2416, @b=374441, @m=1771075>
            irb(main):010:0> f.next
            => 45940
            irb(main):011:0> f.next
            => 1558831
            irb(main):012:0> f.next
            => 1204687
            

            根据 a/b/m 的值,给定种子的结果将是相同的。这可用于在两个地方生成相同的“随机”数,并且双方都可以依赖于获得相同的结果。这对加密很有用;虽然很明显,这个算法在密码学上并不安全。

            【讨论】:

              猜你喜欢
              • 2017-01-25
              • 1970-01-01
              • 1970-01-01
              • 2011-09-06
              • 2013-05-28
              • 2013-05-23
              • 1970-01-01
              • 2013-05-11
              相关资源
              最近更新 更多