【问题标题】:Probability of repeating results using rand.Next()使用 rand.Next() 重复结果的概率
【发布时间】:2011-04-07 03:47:19
【问题描述】:

看着another question of mine,我意识到从技术上讲,没有什么可以阻止这个算法无限期地运行。 (即:它永远不会返回)

因为rand.Next(1, 100000); 理论上可能会继续生成相同的值。

出于好奇;我将如何计算发生这种情况的概率?我认为它会非常小?

其他问题的代码:

Random rand = new Random();
List<Int32> result = new List<Int32>();
for (Int32 i = 0; i < 300; i++)
{
    Int32 curValue = rand.Next(1, 100000);
    while (result.Exists(value => value == curValue))
    {
        curValue = rand.Next(1, 100000);
    }
    result.Add(curValue);
} 

【问题讨论】:

标签: c# algorithm math


【解决方案1】:

在一次给定的随机数抽取中,重复结果列表中容易找到的值的概率为

P(Collision) = i * 1/100000   where i is the number of values in the list.

这是因为假设所有 100,000 个可能的数字都具有相同的被抽中概率(假设均匀分布),并且任何数字的抽奖都独立于任何其他数字的抽奖。

连续几次与列表中的数字发生这种“碰撞”的概率是

P(n Collisions) = P(Collision) ^ n    
   where n is the number of times a collision happens

那是因为图纸是独立的。

Numerically...
   when the list is half full, i = 150 and
                 P(Collision) = 0.15% = 0.0015  and
                 P(2 Collisions) = 0.00000225
                 P(3 Collisions) - 0.000000003375
                 P(4 Collisions) = 0.0000000000050265
   when the list is all full but for the last one, i = 299 and
                 P(Collision) = 0.299% = 0.00299   and
                 P(2 Collisions) = 0.0000089401   (approx)
                 P(3 Collisions) = 0.00000002673  (approx)
                 P(4 Collisions) = 0.000000000079925  (approx)

因此,您可以正确假设必须多次绘制才能找到下一个合适的值添加到数组中的概率非常小,因此不应影响 sn-p 的整体性能。 注意会有几次重试(从统计上讲),但总重试次数会比 300 次少。

但是,如果列表中所需的项目总数要增加很多,或者要减少所寻找的随机数范围,则 P(Collision) 不会那么小,因此需要“重试”的次数会相应增长。这就是为什么存在用于绘制多个值的其他算法无需替换的原因;大多数都是基于使用随机数作为所有剩余值数组的索引的想法。

【讨论】:

    【解决方案2】:

    假设均匀分布(我相信这个假设不错)连续获得 n 次的机会是 (0.00001)^n。

    【讨论】:

      【解决方案3】:

      PRNG 很有可能在连续调用的有限范围内生成相同的数字。概率将是原始 PRNG 的位大小和用于将该大小减小到您想要的数字范围(在本例中为 1 - 100000)的方法的函数。

      【讨论】:

        【解决方案4】:

        要准确回答你的问题,不,它不是很小,它持续无限时间的概率“是”0。我说“是”是因为它实际上趋向于 0 当迭代趋于无穷。

        正如 bdares 所说,如果我们可以假设均匀分布(this 说我们可以),它会在 (1/range)^n 时趋于 0,其中 n 是迭代次数。

        【讨论】:

          【解决方案5】:

          如果出现以下情况,此程序将不会停止:

          1. 在结果集中选择一个随机数
          2. 该数字在随机数生成器的算法中生成一个循环(即循环)(它们都这样做)
          3. 循环中的所有数字都已在结果集中

          所有随机数生成器最终都会自行循环,因为可能的整数数量有限 ==> 对于 32 位,只有 2^32 个可能的值。

          “好”的生成器有非常大的循环。 “差”算法会为某些值产生短循环。请参阅 Knuth 的计算机编程艺术,了解随机数生成器。这是一本引人入胜的读物。

          现在,假设有 (n) 个数字的循环。对于循环 300 次的程序,这意味着 (n)

          假设大多数随机数生成算法具有合理平坦的概率分布,第一次达到 300 个周期的概率为 (300/2^32),乘以具有 300 个周期的概率(这取决于在 rand 算法上),加上第一次达到 299 周期的概率 (299/2^32) x 有 299 周期的概率,等等。等等。然后将第二次尝试、第三次尝试相加,一直到第 300 次尝试(只能是 1 次循环)。

          现在假设任何数字都可以占据完整的 2^32 生成器空间。如果您仅将其限制为 100000,那么本质上您会增加周期更短的机会,因为多个数字(在 2^32 空间中)可以映射到“真实”100000 空间中的相同数字。

          实际上,大多数随机生成器算法的最小循环长度 > 300。基于最简单 LCG(线性同余生成器,wikipedia)的随机生成器实现可以具有“完整周期” (即 2^32)正确选择参数。因此可以肯定地说,最小循环长度肯定 > 300。如果是这种情况,则取决于生成器的映射算法将 2^32 个数字映射为 100000 个数字。好的映射器不会创建 300 个周期,差的映射器可能会创建短周期。

          【讨论】:

          • 您的回答暗示具有 32 位输出的 RNG 最多可以有 2^32 的周期 - 这不是真的。许多 PRNG 具有更大的内部状态,并且周期远远超过 2^32。 任何您可能使用的 PRNG 都会有大大超过此处相关内容的时间段。
          • @Nick Johnson,很酷。不知道 RNG 在 32 位操作系统上内部使用 > 32 位。很高兴知道! +1
          • 硬件和操作系统的地址大小无关——PRNG 可以具有任意大的状态,而不管底层硬件如何。一些 PRNG,例如 LCG,只有与其输出长度一样多的状态,但它们确实往往很差。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-16
          • 2016-03-04
          • 1970-01-01
          • 2021-08-27
          • 2017-10-01
          • 2015-06-24
          相关资源
          最近更新 更多