随机数种子的生成

6

参考资料:链接文本

我无法理解以下这行的意思,请问有人可以给我提供一些下面语句的例子吗?

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


接下来的语句非常简单。Random r1, r2,使用相同的种子创建并初始化(请参阅文档)。对每个对象调用 next 5 次。它们将返回相同的 5 个“随机”数字序列。 - polygenelubricants
6个回答

15

既然您要求一个示例:

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

无论你在什么平台上,使用什么版本的Java,在运行多少次后,两个Random实例的输出始终相同:

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

8
随机生成器是“确定性”的。给定相同的输入到Random和在Random中使用相同方法,返回到您的程序的伪随机数序列将在不同的机器上的不同运行中保持相同。
这就是为什么它是伪随机的 - 返回的数字在统计学上表现得像随机数,除了它们可以被可靠地预测。真正的随机数是不可预测的。

3

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


2
这些数字并不是真正的随机数,因为在相同的起始条件(种子)和相同的操作序列下,将生成相同的数字序列。这就是为什么在任何加密或安全相关代码中使用基本的Random类都不是一个好主意,因为攻击者可能会找出正在生成的序列并预测未来的数字。
如果需要发出非确定性值的随机数生成器,请查看SecureRandom
有关更多信息,请参见维基百科上的随机数生成,计算方法

1

这意味着当你创建随机对象时(例如在程序开始时),你可能想要用一个新的种子开始。大多数人选择一些与时间相关的值,例如滴答数。

如果给定相同的种子,数字序列是相同的这一事实实际上非常方便,如果您想调试程序,确保记录种子值,如果有什么问题,您可以使用相同的种子值在调试器中重新启动程序。这意味着您可以完全重现该场景。如果使用真正的随机数生成器,这是不可能的。


0

使用相同的种子值,隔离的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的值,对于给定的种子,结果将是相同的。这可以用于在两个地方生成相同的“随机”数,并且双方都可以依赖于获得相同的结果。这对加密很有用;尽管显然,这个算法并不具备密码学安全性。

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