平均而言,这个不正确的循环会重复多少次?

时间:2013-04-19 19:19:15

标签: math random for-loop language-agnostic

在某些情况下,循环需要运行一系列从minmax的随机迭代次数。一个有效的解决方案是做这样的事情:

int numIterations = randomInteger(min, max);
for (int i = 0; i < numIterations; i++) {
   /* ... fun and exciting things! ... */
}

许多初学程序员常犯的一个错误就是这样做:

for (int i = 0; i < randomInteger(min, max); i++) {
   /* ... fun and exciting things! ... */
}

这会重新计算每次迭代的循环上限。

怀疑这不会给出循环迭代次数的统一分布,范围从minmax,但我不确定当你做这样的事情时,你做什么得到的确切分布。有谁知道循环迭代次数的分布是什么?

作为一个具体示例:假设min = 0且max = 2.然后有以下可能性:

  • i = 0时,随机值为0.循环运行0次。
  • i = 0时,随机值非零。然后:
    • i = 1时,随机值为0或1.然后循环运行1次。
    • i = 1时,随机值为2.然后循环运行2次。

第一次事件的概率是1/3。第二个事件的概率为2/3,在其中,第一个子案例的概率为2/3,第二个事件的概率为1/3。因此,平均分布数是

  

1 / 3 + 1× 2 / 3 × 2 / 3 + 2× 2 / 3 × 1 / 3

     

= 0 + 4 / 9 + 4 / 9

     

= 8 / 9

请注意,如果分布确实是均匀的,我们期望得到1次循环迭代,但现在我们平均只获得 8 / 9 。我的问题是,是否有可能推广这个结果以获得更精确的迭代次数值。

谢谢!

4 个答案:

答案 0 :(得分:5)

最后编辑(也许!)。我敢肯定这不是standard distributions that are appropriate之一。我已经把这个发布的内容放在了这篇文章的底部,因为我认为提供概率的代码更具可读性!下面给出了针对max的平均迭代次数的图表。

enter image description here

有趣的是,当你增加最大值时,迭代次数会减少。如果其他人可以用他们的代码确认这一点,那将会很有趣。

如果我开始对此进行建模,我将从geometric distribution开始,并尝试修改它。基本上我们正在寻找一个离散的,有界的分布。所以我们有零个或多个“失败”(不符合停止条件),然后是一个“成功”。与几何或泊松相比,这里的捕获是成功的概率变化(同样,泊松,几何分布是无界的,但我认为结构上几何是一个很好的基础)。假设min = 0,P(X = k)的基本数学形式,0 <= k <= max,其中k是循环运行的迭代次数,与几何分布一样,是k次失败的乘积术语和1个成功术语,对应于循环条件下的k“假”和1“真”。 (注意,这甚至可以计算最后的概率,因为停止的几率是1,这显然对产品没有影响。)

接下来,尝试在R中的代码中实现它,如下所示:

fx = function(k,maximum)
{
    n=maximum+1;
    failure = factorial(n-1)/factorial(n-1-k) / n^k;
    success = (k+1) / n;
    failure * success
}

这假定min = 0,但推广到任意min并不困难(参见我对OP的评论)。解释代码。首先,如OP所示,概率都以(min+1)为分母,因此我们计算分母n。接下来,我们计算失败条款的乘积。这里factorial(n-1)/factorial(n-1-k)表示例如min = 2,n = 3和k = 2:2 * 1。并且它通常给你(n-1)(n-2) ...表示失败的总概率。随着你进一步进入循环,成功的概率会增加,直到最后,当k=maximum时,它是1。

绘制此分析公式可得到与OP相同的结果,形状与John Kugelman绘制的模拟相同。

enter image description here

顺便提一句,执行此操作的R代码如下

plot_probability_mass_function = function(maximum)
{
    x=0:maximum;
    barplot(fx(x,max(x)), names.arg=x, main=paste("max",maximum), ylab="P(X=x)");
}

par(mfrow=c(3,1))
plot_probability_mass_function(2)
plot_probability_mass_function(10)
plot_probability_mass_function(100)

在数学上,如果我的数学是正确的,则分布是:

enter image description here

简化为

enter image description here

(感谢一大堆http://www.codecogs.com/latex/eqneditor.php

后者由R函数

给出
function(x,m) { factorial(m)*(x+1)/(factorial(m-x)*(m+1)^(x+1)) }

在R

中绘制平均迭代次数
meanf = function(minimum)
{
    x = 0:minimum
    probs = f(x,minimum)
    x %*% probs
}

meanf = function(maximum)
{
    x = 0:maximum
    probs = f(x,maximum)
    x %*% probs
}

par(mfrow=c(2,1))
max_range = 1:10
plot(sapply(max_range, meanf) ~ max_range, ylab="Mean number of iterations", xlab="max")
max_range = 1:100
plot(sapply(max_range, meanf) ~ max_range, ylab="Mean number of iterations", xlab="max")

答案 1 :(得分:2)

以下是我用matplotlib绘制的一些具体结果。 X轴是达到的值i。 Y轴是达到该值的次数。

分布显然不均匀。我不知道它的分布是什么;我的统计知识很生疏。

1。 min = 10,max = 20,iterations = 100,000

2。 min = 100,max = 200,iterations = 100,000

答案 2 :(得分:0)

我认为,如果有足够数量的执行,它仍然符合randomInteger函数的分布。

但这可能是一个更适合MATHEMATICS询问的问题。

答案 3 :(得分:0)

我不知道它背后的数学,但我知道如何计算它!在哈斯克尔:

import Numeric.Probability.Distribution

iterations min max = iteration 0
  where
  iteration i = do
    x <- uniform [min..max]
    if i < x
      then iteration (i + 1)
      else return i

现在expected (iterations 0 2)为您提供了〜0.89的预期值。也许拥有必要数学知识的人可以解释我在这里做的事情。因为从0开始,循环将始终至少运行min次。