随机数生成器:类级别还是方法级别?

时间:2008-11-25 11:21:08

标签: random correctness

使用随机数生成器时,这是更好的方法来使用它来获得新值的更大随机性:

  1. 有一个方法每次都实例化一个新的RNG实例,然后返回一个值吗?

  2. 在类级别有一个RNG实例,它在构造函数中实例化一次,以及所有后续使用现有实例调用新的随机值?

  3. 问题在于可能会有很多调用随机数,通常是在不相关的范围内。

    这不是性能问题,因此每个调用可能实例化一个新实例的事实没有任何区别。这完全是关于返回值的随机性。

3 个答案:

答案 0 :(得分:8)

实际上,选项1不起作用。

选项2是唯一的选择。 RNG绝对要求您从单个种子中依次生成值。

你的“用新种子创造一个新的发电机”打破了数学基础。你得到的完全取决于你的种子,遗憾的是 - 它不会非常随机。

答案 1 :(得分:4)

我建议选项3:在整个计划中使用一个RNG。如果RNG不是线程安全的(例如在.NET中),它需要锁定或线程本地,但它使生活变得更简单,并且您不必担心重复。

有关我为此目的而编写的.NET StaticRandom类的详细信息,请参阅the relevant MiscUtil page。 (这非常简单 - 根本不聪明。)

答案 2 :(得分:3)

编辑:我认为我的意思是选项3,正如另一个答案中提到的那样,即一个全局随机管理器,尽管在特定的类中你可以做同样的事情。

使用选项2的另一个优点是,如果您在软件中需要“重放”功能,则可以简单地存储用于初始化RNG的种子。下一次,您只需要强制RNG使用存储的种子,您将获得完全相同的行为,假设没有其他问题,如并发/线程可能会改变执行顺序

如果您的软件正在运行需要大量随机性的实验,您可能希望执行此类操作,但您可能希望重复特定运行以向其他人演示。它也在计算机游戏中被大量使用,其中AI将根据可能的选择权重做出决定,但最终会随机抽取一个“挑选”他们采取的行动。

它还可以调试偶尔出现的瞬态错误。如果您不存储每次运行的种子,则无法重新创建导致该错误的确切条件。