使用Array.prototype.reduce
(或Array.prototype.reduceRight
)的签名,是否有可能从数组中为所有索引选择具有相等概率的项目?这是我的尝试:
document.write(`
${[...'abcdefghijklmnopqrstuvwxyz'].reduce(function(last, next, index, array) {
if (Math.random() > index / array.length) {
return next;
}
return last;
})}
`);
经过几次测试运行后,分布似乎偏向于较低的索引(也就是说,较高的索引被更频繁地选择)。
您可以为此使用储层采样:始终选择第一个元素,然后在遍历数组时,以概率用第k个(基于1的索引)项替换当前选择的项1/k
。这将给您统一的概率:
document.write(`
${[...'abcdefghijklmnopqrstuvwxyz'].reduce(function(last, next, index, array) {
if ( Math.random()*(index + 1) <= 1 ) {
return next;
}
return last;
})}
`);
这是一个测试证明它确实以相同的概率返回每个字母:
var results = {};
for ( var i = 0; i < 100000; i++ ) {
var choice = [...'abcdefghijklmnopqrstuvwxyz'].reduce(function(last, next, index, array) {
if ( Math.random()*(index + 1) <= 1 ) {
return next;
}
return last;
} );
results[ choice ] = (results[ choice ] || 0) + 1;
}
document.body.innerHTML = '<pre>' + JSON.stringify( results, '\t' ) + '</pre>';
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句