使用带有偏差的 Random()
Using Random() with a Bias
假设我有一个数组
var list = ['a', 'b', 'c', 'd'];
我想从 List
中随机 select 一个值。如果是完全随机的,则每个都有 25% 的机会。有没有办法随机 select 一个带有偏差的值,如下所示:
var bias = [0.1, 0.2, 0.1, 0.6];
(偏差当然加起来为 1)
所以 'a' 有 10% 的机会被 selected 和 'b' 有 20% 的机会被 selected, 等等
编辑:我知道我可以随机修改 do var list = ['a', 'b', 'b', 'c', 'd', 'd', 'd', 'd', 'd', 'd']
和 select 一个值,但我正在寻找一种更有效的方法,只需要一个包含偏见。
制作一个累积偏差列表:
var sum = 0;
var cumulativeBias = bias.map(function(x) { sum += x; return sum; });
然后从0
到sum
(即cumulativeBias[cumulativeBias.length - 1]
)做一个随机数:
var choice = Math.random() * sum;
然后搜索cumulativeBias
中第一个大于choice
的元素。您可以使用二进制搜索来提高速度,但对于短列表,顺序搜索就足够了。该元素的索引是选定的索引。例如,类似于:
var chosenIndex = null;
cumulativeBias.some(function(el, i) {
return el > choice ? ((chosenIndex = i), true) : false;
});
chosenElement = list[chosenIndex];
我以前是这样写的:
用 运行 总数替换您的偏差 - 即,将偏差 [0] 添加到偏差 [1],然后将偏差 [1] 添加到偏差 [2],然后将偏差 [2] 添加到偏差 [ 3].
在你上面的例子中,你会得到 var bias = [0.1, 0.3, 0.4, 1.0]
- 最后一个应该总是 1,否则你做错了什么。
现在在 0 到 1.0 之间选择一个随机数;在偏差数组中找到最大的数字,该数字小于您的随机数。从列表数组中选择相应的值。
编辑:@Amadan 是对的。我的意思是,在偏置数组中找到比随机数大的最小数字。我的 "smallest" 和 "largest" 是错误的方法:)
因为你的偏见很简单,你可以像这样制作一个提供 10% 'a'
、20% 'b'
等等的数组,然后从中选择一个随机值:
var choices = ['a', 'b', 'b', 'c', 'd', 'd', 'd', 'd', 'd', 'd'];
var biasVal = choices[Math.floor(Math.random() * choices.length)];
如果需要,可以通过编程方式构建选择数组。它只需要构建一次,从那时起,使用这种方法随机选择的选择将明显更快。
假设我有一个数组
var list = ['a', 'b', 'c', 'd'];
我想从 List
中随机 select 一个值。如果是完全随机的,则每个都有 25% 的机会。有没有办法随机 select 一个带有偏差的值,如下所示:
var bias = [0.1, 0.2, 0.1, 0.6];
(偏差当然加起来为 1)
所以 'a' 有 10% 的机会被 selected 和 'b' 有 20% 的机会被 selected, 等等
编辑:我知道我可以随机修改 do var list = ['a', 'b', 'b', 'c', 'd', 'd', 'd', 'd', 'd', 'd']
和 select 一个值,但我正在寻找一种更有效的方法,只需要一个包含偏见。
制作一个累积偏差列表:
var sum = 0;
var cumulativeBias = bias.map(function(x) { sum += x; return sum; });
然后从0
到sum
(即cumulativeBias[cumulativeBias.length - 1]
)做一个随机数:
var choice = Math.random() * sum;
然后搜索cumulativeBias
中第一个大于choice
的元素。您可以使用二进制搜索来提高速度,但对于短列表,顺序搜索就足够了。该元素的索引是选定的索引。例如,类似于:
var chosenIndex = null;
cumulativeBias.some(function(el, i) {
return el > choice ? ((chosenIndex = i), true) : false;
});
chosenElement = list[chosenIndex];
我以前是这样写的:
用 运行 总数替换您的偏差 - 即,将偏差 [0] 添加到偏差 [1],然后将偏差 [1] 添加到偏差 [2],然后将偏差 [2] 添加到偏差 [ 3].
在你上面的例子中,你会得到 var bias = [0.1, 0.3, 0.4, 1.0]
- 最后一个应该总是 1,否则你做错了什么。
现在在 0 到 1.0 之间选择一个随机数;在偏差数组中找到最大的数字,该数字小于您的随机数。从列表数组中选择相应的值。
编辑:@Amadan 是对的。我的意思是,在偏置数组中找到比随机数大的最小数字。我的 "smallest" 和 "largest" 是错误的方法:)
因为你的偏见很简单,你可以像这样制作一个提供 10% 'a'
、20% 'b'
等等的数组,然后从中选择一个随机值:
var choices = ['a', 'b', 'b', 'c', 'd', 'd', 'd', 'd', 'd', 'd'];
var biasVal = choices[Math.floor(Math.random() * choices.length)];
如果需要,可以通过编程方式构建选择数组。它只需要构建一次,从那时起,使用这种方法随机选择的选择将明显更快。