假设我在数组中有两个项目,例如:
["a", "b"]
现在假设我有一个名为random的函数,它从这个数组中选择一个随机项,例如:
function random() {
// do awesome random stuff here...
return random_choice;
}
如何让random
函数在80%的时间内返回"a"
并在20%的时间内返回"b"
?
我不确定这是什么叫做但是例如如果我运行console.log(random());
10次,结果应该看起来像这样:
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "b"
>>> "b"
"a"
获得8/10次返回,"b"
返回2/10次。
注意:上面的“结果”只是一个例子,我知道它们并不总是那么完美而且它们不一定是。< / p>
答案 0 :(得分:6)
最快的答案是:
var result = Math.random() >= 0.2 ? "a" : "b";
答案 1 :(得分:2)
Math.random()
返回[0; 1]中的数字。只需使用p < 0.2
/ p < 0.8
即可获得有偏见的结果,而不是无偏见的p < 0.5
。
如果您希望前N个结果具有确定性,那么您可以使用简单的计数器i++ < N
。
答案 2 :(得分:1)
有点扩展:
var array="a".repeat(8)+"b".repeat(2);
var random=()=>array[Math.floor(Math.random()*array.length)];
alert(random());
这也适用于两种以上的结果和所有不同的概率。
请注意,数组实际上不是数组,而是lookupstring ..
答案 3 :(得分:1)
适用于任意数量值的广义解决方案
function biasedRandomSelection(values, probabilities) {
// generate random number (zero to one).
var rand = Math.random();
// cumulative probability, starting at 0
var cumulativeProb = 0;
// loop through the raw `probabilities` array
for(var i=0; i<probabilities.length; i++) {
// increment cumulative probability
cumulativeProb += probabilities[i];
// test for `rand` being less than the cumulative probaility;
// when true, return return the corresponding value.
if(rand < cumulativeProb) return values[i];
}
}
这里的诀窍是测试从原始概率中得出的滚动“累积概率”。
示例电话:
biasedRandomSelection(['a', 'b'], [0.8, 0.2]); // as per the question
biasedRandomSelection(['a', 'b'], [0.2, 0.8]); // reversed probailities
biasedRandomSelection(['a', 'b', 'c', 'd', 'e'], [0.4, 0.1, 0.2, 0.2, 0.1]); // larger range of values/probailities
<强> Demo 强>
如上所述,biasedRandomSelection()
不执行范围检查。
更安全的版本会检查:
values
和probabilities
是一致的probabilities
的总和为1。