在某些情况下,循环需要运行一系列从min
到max
的随机迭代次数。一个有效的解决方案是做这样的事情:
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! ... */
}
这会重新计算每次迭代的循环上限。
我怀疑这不会给出循环迭代次数的统一分布,范围从min
到max
,但我不确定当你做这样的事情时,你做什么得到的确切分布。有谁知道循环迭代次数的分布是什么?
作为一个具体示例:假设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。因此,平均分布数是
0× 1 / 3 + 1× 2 / 3 × 2 / 3 + 2× 2 / 3 × 1 / 3
= 0 + 4 / 9 + 4 / 9
= 8 / 9
请注意,如果分布确实是均匀的,我们期望得到1次循环迭代,但现在我们平均只获得 8 / 9 。我的问题是,是否有可能推广这个结果以获得更精确的迭代次数值。
谢谢!
答案 0 :(得分:5)
最后编辑(也许!)。我敢肯定这不是standard distributions that are appropriate之一。我已经把这个发布的内容放在了这篇文章的底部,因为我认为提供概率的代码更具可读性!下面给出了针对max
的平均迭代次数的图表。
有趣的是,当你增加最大值时,迭代次数会减少。如果其他人可以用他们的代码确认这一点,那将会很有趣。
如果我开始对此进行建模,我将从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绘制的模拟相同。
顺便提一句,执行此操作的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)
在数学上,如果我的数学是正确的,则分布是:
简化为
(感谢一大堆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轴是达到该值的次数。
分布显然不均匀。我不知道它的分布是什么;我的统计知识很生疏。
答案 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
次。