循环中的随机数生成问题
本文解决了在循环中使用 Random.Next()
时遇到的常见问题:连续迭代产生相同的随机数。 当多个 Random
对象快速连续实例化时,此问题通常会出现。
问题场景:
考虑以下代码片段:
<code class="language-csharp">class A { Random rnd = new Random(); public void Count() { int r1 = rnd.Next(-1, 1); int r2 = rnd.Next(-1, 1); // ... further code using r1 and r2 ... } } class B { List<A> listOfA = new List<A>(); public B() { // ... populate listOfA ... foreach (A instance in listOfA) { instance.Count(); } } }</code>
如果 listOfA
包含类 A
的多个实例,则每个 A
对象都会创建自己的 Random
实例。 由于高速实例化,这些Random
对象可能会收到相同的种子值(通常来自系统时钟),从而产生相同的随机数序列。
根本原因:
问题源于默认的 Random
构造函数依赖系统时钟进行播种。 如果在很短的时间内创建多个 Random
对象,它们会收到几乎相同的种子值,从而生成相同的伪随机数。
解决方案:单个随机实例
解决方案很简单:创建一个 Random
实例并在类 A
的所有实例中重用它。 这可确保生成唯一的、不重复的随机数序列。
这是更正后的代码:
<code class="language-csharp">class A { private Random rnd; public A(Random rnd) { this.rnd = rnd; } public void Count() { int r1 = rnd.Next(-1, 1); int r2 = rnd.Next(-1, 1); // ... further code using r1 and r2 ... } } class B { Random rnd = new Random(); List<A> listOfA = new List<A>(); public B() { // ... populate listOfA, passing rnd to the constructor ... foreach (A instance in listOfA) { instance.Count(); } } }</code>
通过将单个 Random
实例 (rnd
) 注入到 A
类构造函数中,我们保证对 rnd.Next()
的所有调用都来自相同的、正确的种子序列。 这有效地消除了重复随机数的生成。
以上是为什么随机次数在连续的循环迭代中产生相同的值?的详细内容。更多信息请关注PHP中文网其他相关文章!