我在Javascript中编写了一个显示随机图片的litte函数。返回图片编号的实际行如下所示:
num = Math.floor(Math.random() * RNDGALSIZE);
目前RNDGALSIZE = 72。
但是,我觉得有些图片经常被点击而有些图片很长时间没有出现,所以我编写了一个循环来生成num
一些次,并记录num
的每个值的次数{{ 1}}出现了。结果如下:
2, 1, 2, 1, 1, 3, 1, 2, 2, 2, // num = 0 to 9
2, 1, 0, 1, 0, 2, 2, 1, 0, 1, // num = 10 to 19
1, 2, 0, 1, 0, 0, 1, 1, 2, 1, // num = 20 to 29
1, 0, 1, 2, 0, 2, 1, 0, 0, 0, // num = 30 to 39
2, 2, 3, 3, 0, 1, 1, 1, 0, 3, // num = 40 to 49
2, 1, 2, 1, 3, 2, 3, 2, 1, 1, // num = 50 to 59
2, 1, 1, 0, 0, 2, 2, 1, 0, 1, // num = 60 to 69
3, 1 // num = 70 and 71
正如您所看到的,没有任何值出现超过3次,并且根本没有出现16个值。虽然某些值可能不会发生,但我认为16是很多。我的方法有什么问题吗?
更新
稍后:
4, 4, 3, 6, 5, 5, 3, 3, 2, 2,
2, 2, 2, 2, 3, 5, 3, 1, 4, 2,
4, 3, 0, 1, 1, 0, 1, 4, 4, 4,
2, 0, 5, 3, 0, 4, 2, 0, 2, 1,
2, 3, 4, 3, 2, 4, 3, 2, 0, 5,
4, 4, 4, 2, 3, 4, 4, 4, 5, 1,
2, 2, 4, 2, 0, 3, 4, 2, 2, 1,
4, 1,
正如你所看到的,当3被击中6次时,数组中仍有7个零:/
答案 0 :(得分:3)
(这是详细说明失败者的回答。)
让p[n][k]
表示在n
次试验后,出现的确切k
个不同值(72个)中的概率。很难给出一个精确的闭式表达式,但我们可以使用动态编程很容易地计算它:
var p = [];
p[0] = [];
p[0][0] = 1; // after 0 trials, 100% chance that 0 values have appeared
for(var k = 1; k <= 72; ++k) {
p[0][k] = 0
}
for(var n = 1; n < 1000; ++n) {
p[n] = [];
p[n][0] = 0;
for(var k = 1; k < n && k <= 72; ++k) {
p[n][k] = p[n-1][k] * k / 72 + p[n-1][k-1] * (72-k+1) / 72;
}
if(n <= 72) {
p[n][n] = p[n-1][n-1] * (72-n+1) / 72;
}
for(var k = n + 1; k <= 72; ++k) {
p[n][k] = 0;
}
}
鉴于此,我们可以计算在n
次试验后,我们仍然至少有z
个“零”的概率(即使没有出现过一次的值):
function probabilityAfterNTrialsOfAtLeastZZeroes(n, z) {
var ret = 0;
for(var k = 0; k <= 72 - z; ++k) {
ret += p[n][k];
}
return ret;
}
因此,在91次试验之后,我们仍然有16个或更多“零”的概率是probabilityAfterNTrialsOfAtLeastZZeroes(91, 16)
,即0.959,即96%。 (实际上,你的很少实际上有点令人惊讶:拥有17个或更多“零”的概率为0.914,因此16个或更少的概率仅为8.6%。)
类似地,在194次试验之后,我们仍有7个或更多“零”的概率是probabilityAfterNTrialsOfAtLeastZZeroes(194, 7)
,即0.179,即18%。因此,在194次试验之后,你通常会期望少于7个“零”,但如果你多次重复实验,你可能会在五次中几乎每次都有7个或更多的“零”。
我们还可以计算n
次试验后预期的“零”数:
function expectedZeroesAfterNTrials(n) {
var ret = 0;
for(var z = 0; z <= 72; ++z) {
ret += z * p[n][72-z];
}
return ret;
}
经过91次试验,我们预计expectedZeroesAfterNTrials(91)
“零”,即20.164,经过194次试验,我们预计会有4.775“零”。
答案 1 :(得分:1)
你的数字看起来很合理,
Math.pow((71/72),194)*72 // odds of missing a number ^ tries * number of slots
4.774719247726743
由于我们无法得到一个分数,如果我们生活在“确定性随机”世界中,看起来你应该有5而不是7“零”。
相反,您应该选择不替换,然后在0处重新启动池。
编辑可以从jsconsole运行的快速且脏的100测试计数:
function do_test() { x = []; for (var i = 0 ; i < 72 ; i++) x.push(0); for (var j = 0; j < 194; j++) x[Math.floor(Math.random()*72)]++; count = 0; for (var i = 0 ; i < 72 ; i++) if (!x[i]) count++; return count;}
function do_tests(n) { y = []; for (var i = 0; i < n; i++) y.push(do_test()); return y;}
z = do_tests(100)
[5,5,3,6,4,3,2,4,3,3,4,5,2,5,5,3,7,3,3,4,6,4,7, 4,3,7,5,5,3,3,3,4,5,3,3,3,8,3,4,7,8,4,6,3,4,3,4,3, 2,7,6,7,7,5,3,6,1,3,6,5,3,3,5,4,4,5,3,4,6,6,4,3,3, 7,4,11,6,5,9,5,3,6,7,6,9,2,1,7,3,4,4,6,6,7,7,5,2,5, 9,6]
j = 0; for (var i = 0; i < 100; i++) j+=z[i];
473 //所以4.73零时隙是这100次运行的平均值......
答案 2 :(得分:0)
因此,解决方案是跟踪一个数字被击中的频率,以防随机发生器命中一个已经经常被击中的数字,提供一个经常被忽略的数字......
var minhit = Number.MAX_VALUE;
var maxhit = 1;
var index_min = 0;
for (i=0; i<RNDGALSIZE; i++)
{
if (imgnum[i] < minhit)
{
minhit = imgnum[i];
index_min = i;
}
else if (imgnum[i]>maxhit)
{
maxhit = imgnum[i];
}
}
var num = Math.floor(Math.random() * RNDGALSIZE);
if (imgnum[num] == maxhit)
{
num = index_min;
}
imgnum[num]++;
结果:
2, 2, 1, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1,
1, 1,