我最近运行并测试了以下代码以在网页上执行。对于访问我的网页的每个人来说,这段代码应该在他们查看页面之前运行,以便随机地将50%的代码汇集到一个不同的网页中。根据我的理解(和测试)生成的代码(见下文)生成1到10之间的随机数。编译并运行1000次后,我确认生成1,2,3,4,5大约50%的时间和6,7,8,9,10产生50%。因此,我希望根据我的代码,任何拥有1,2,3,4或5的人都符合if语句的标准。
var rando = Math.floor((Math.random() * 10) + 1);
if(rando < 6){
//execute unrelated jquery code here to modify webpage
}
不幸的是,网页上的执行无法按计划运行。在我的网页的250个唯一访问者中,100个触发了if语句,150个没有触发。虽然这显然是随机机会的结果,但它可能更有可能是我遗漏的一些错误的根源。如上所述,我测试了这段代码,发现它正在生成我希望在堆栈交换上研究这个特定问题的分布,虽然在某些情况下似乎存在随机数生成器的偏差,但我认为我不认为代码遇到了这个问题。任何帮助或见解将不胜感激!
答案 0 :(得分:1)
简化事物..生成0到1之间的随机数。看看这段代码。命中运行,每次约为50%。
var count = 0;
var numTimes = 10000;
for(var i = 0; i < numTimes; i++)
{
var rando = Math.floor((Math.random() * 2));
if(rando === 1){
count++;
}
}
console.log(count/numTimes);
答案 1 :(得分:1)
运行此代码时,您会注意到伪随机值的不同分布。当样本数量较少时,差异可能更明显。 作为Math.random depends of browser's JavaScript engine implementation的输出,它可能会使您的案例的分布不令人满意。
您也可以使用cryptographically random values - 更难实现,但应该为您提供更均匀的分发。 random-js似乎已实施此API。
function test(times) {
var t = times;
var a = 0;
var b = 0;
while(t --> 0) {
var rando = Math.floor((Math.random() * 10) + 1);
if(rando < 6){
a++;
}
else {
b++;
}
}
console.log("TEST FOR " + times);
console.log(a);
console.log(b);
console.log("DISTRIBUTION");
console.log((100 * a/(a + b)).toFixed(2) + "%");
}
test(250);
test(250);
test(250);
test(1024);
test(2048);
test(4096);
test(8192);
test(32768);
在下方,您可以看到crypto.getRandomValues
实施。 1000多个样本的分布几乎保证非常接近50%。
function test(times) {
var t = times;
var a = 0;
var b = 0;
var array = new Uint32Array(times / 32);
window.crypto.getRandomValues(array);
for (var i = 0; i < array.length; i++) {
var bitString = array[i].toString(2);
for (var j = 0; j < 32; j++) {
if(j < bitString.length && bitString[j] === '1')
a++;
else
b++;
}
}
console.log("TEST FOR " + times);
console.log(a);
console.log(b);
console.log("DISTRIBUTION");
console.log((100 * a/(a + b)).toFixed(2) + "%");
}
test(256);
test(256);
test(256);
test(1024);
test(2048);
test(4096);
test(8192);
test(32768);