使用Random.setSeed的重要性是什么?

时间:2013-07-10 08:07:27

标签: java random

编写Java程序时,我们在Random类中使用setSeed。我们为什么要使用这种方法?

我们不能在不使用Random的情况下使用setSeed吗?使用setSeed的主要目的是什么?

5 个答案:

答案 0 :(得分:10)

这样做的一个用途是,它使您能够在将来重现您的计划结果。

作为一个例子,我想为数据库中的每一行计算一个随机变量。我希望程序可以重现,但我希望行之间的随机性。为此,我将随机数种子设置为每行的主键。这样,当我再次运行程序时,我得到了相同的结果,但在行之间,随机变量是伪随机的。

答案 1 :(得分:3)

种子用于初始化随机数生成器。种子用于设置生成一系列随机数的起点。种子将发生器设置为随机起始点。唯一种子返回唯一的随机数序列。

This可能有所帮助。

  

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

答案 2 :(得分:3)

我可以看到这样做的两个原因:

  1. 您可以创建可重现的随机流。对于给定的种子,将从连续调用(相同)nextX方法返回相同的结果。

      

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

  2. 您觉得,由于某种原因,您的种子质量高于默认来源(我猜测它来自您PC上的当前时间)。

答案 3 :(得分:3)

特定种子将始终给出相同的“随机”数字序列。所以在Random中只有2 ^ 64个不同的序列!除setSeed之外,还可以使用带种子的构造函数。当使用时,种子使用计算机的时钟来选择真正随机的种子。

因此,在普通情况下,不使用特定种子,构造函数Random() setSeed。 尤其要避免setSeed(System.currentTimeMillis())

对于数据相关调试,您希望重复相同的伪随机数据,请使用特定种子。

由于种子种类繁多,无需担心特定的种子/序列是否会被识别,后续数字是否会被预测。

当谈论成千上万的{{​​1}}时,默认构造函数使用System.nanoTime()(适当地损坏),这是一个代价高昂的操作系统功能。

答案 4 :(得分:1)

其他几个人提到了再现性。重现性是调试的核心,您需要能够重现错误发生的环境。

再现性的另一个重要用途是你可以玩一些统计游戏来减少某些估计的可变性。有关详细信息,请参阅Wikipedia's Variance Reduction article,但直觉如下。假设您正考虑为银行或杂货店设置两种不同的布局。您无法构建它们并查看哪个更好,因此您可以使用模拟。从排队理论中你知道,客户体验的线路和延迟的大小部分是由于布局,但也部分是由于到达时间,需求负载等的变化,所以你在两个模型中使用随机性。如果您完全独立地运行模型,并且发现布局1中的线条比布局2中的线条更大,则可能是因为布局或者可能是因为布局1恰好是为了获得更多客户或更苛刻的交易组合由于平局的运气。但是,如果两个系统都使用完全相同的客户同时到达且具有相同的交易需求,则它是一个更公平的"比较。您观察到的差异更可能是因为布局。你可以通过在两个系统中重现随机性来实现这一点 - 使用相同的种子,并进行同步,以便在两个系统中使用相同的随机数用于相同的目的。