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

发布于 2024-07-09 13:05:32 字数 282 浏览 5 评论 0原文

使用随机数生成器时,哪种方法可以更好地使用它来获得更大的新值随机性:

  1. 是否有一种方法可以每次实例化 RNG 的新实例,然后返回一个值?

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

问题是可能有很多对随机数的调用,通常是在彼此不相关的不同范围内。

这不是性能问题,因此每次调用都可能实例化一个新实例这一事实没有什么区别。 这都与返回值的随机性有关。

When using a Random Number Generator, which is the better way to use it for greater randomness of the new value:

  1. Have a method that instantiates a new instance of the RNG each time and then returns a value?

  2. Have an instance of the RNG at the class level, which is instantiated once in the Constructor, and all subsequent calls for a new random value using the existing instance?

The issue is that there may be many calls for a random number, often in different scopes not connected with each other.

This is not a performance issue, so the fact that each call might instantiate a new instance makes no difference. This is all about the randomness of the returned value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猥琐帝 2024-07-16 13:05:32

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

选项2是唯一的选择。 RNG 绝对要求您从单个种子按顺序生成值。

你的“用新种子创建一个新的生成器”打破了数学基础。 然后你得到什么完全取决于你的种子,不幸的是,它不会是非常随机的。

Option 1 does not work, actually.

Option 2 is the only choice. RNG's absolutely require that you generate the values in sequence from a single seed.

Your "create a new generator with a new seed" breaks the mathematical foundation. What you get then totally depends on your seeds, which -- sadly -- won't be very random.

好菇凉咱不稀罕他 2024-07-16 13:05:32

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

有关 .NET StaticRandom 类的详细信息,请参阅相关 MiscUtil 页面我就是为了这个目的而写的。 (这非常简单——一点也不聪明。)

I suggest option 3: have a single RNG used throughout the program. It requires locking or a thread-local if the RNG isn't thread-safe (e.g. in .NET), but it makes life a lot simpler and you don't need to worry about repetition.

See the relevant MiscUtil page for details of the .NET StaticRandom class I wrote for this very purpose. (It's incredibly simple - nothing clever at all.)

眼泪也成诗 2024-07-16 13:05:32

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

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

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

它还使得调试偶尔出现的暂时性错误成为可能。 如果您不存储每次运行的种子,则无法重新创建导致错误的确切条件。

Edit: I believe I mean option 3, as mentioned in another answer, i.e a global random manager, although within a specific class you can doe exactly the same thing.

Another advantage of using Option 2 is that if you ever require "replay" functionality in your software, you can simply store the seed which you used to initialise the RNG. Next time, you only need to force the RNG to use the stored seed and you will get the exact same set of behaviour, assuming that there are not other issues such as concurrency / threading which might change the order of execution.

You might want to do something like this if your software is running an experiment which requires a lot of randomness, but where you might wish to repeat a particular run to demonstrate to other people. It's also used a lot in computer games where the AI will take decisions based on weightings of possible choices, but with ultimately a random number "picking" what action they take.

It also makes debugging possible for transient bugs which only appear occasionally. If you don't store the seed of each run there is no way to recreate the exact conditions which caused the bug.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文