我很难找到任何有助于解决这个问题的资源:
假设我想生成一个介于1和5之间的随机数,但希望将随机化加权到底端(就像生成一对夫妇可能拥有的随机数的孩子一样,这更可能是1比5 )。我应该从哪里开始?这会涉及创建一个复杂的函数来映射该曲线,还是有一种方法可以帮助解决这个问题?
对于非常简单的集合,我想我可以创建一个数组,所以对于上面的例子我可以做,例如:
var children = [1,1,1,1,2,2,2,3,4,5];
return children[Math.floor(Math.random() * children.length)];
但这缺乏灵活性,并假设数据集是在脚本中手动创建的。
答案 0 :(得分:5)
“儿童出生概率”具有高斯分布,这是二项分布的“连续极限”。如何使用binomial distribution?
var val = Math.random()*5 + Math.random()*5;
// "val" will be between 0 and 10, but values around 5 are more probable
return 1 + Math.floor(Math.abs(val-5));
只需将其置于功能中并使“5”成为参数。
小测试(http://jsfiddle.net/yt6zvs8n/):
100个输出值:1,1,2,3,2,4,2,2,3,3,1,2,1,4,1,2,3,2,1,4,4 ,2,1,4,3,2,2,1,3,2,4,1,3,2,4,2,2,1,2,1,1,1,4,1,4,1 ,3,1,2,1,2,1,2,2,3,2,1,3,1,2,1,3,2,1,1,1,1,2,1,1,2 ,1,3,4,1,3,1,2,5,1,3,1,3,1,3,1,4,1,3,1,3,2,2,3,1,3 ,4,1,3
出现(直方图):38,28,21,12,1
答案 1 :(得分:3)
只要您使用整数,其中N是最大子值并且N不是那么大,您将需要O(n)空间和时间
我会回答假设你只使用从0
到N
的整数,请参阅我的答案的 USAGE 部分,为什么你不需要指定它们当他们的体重为0时用手。
var weights = [0,4,3,1,1,1];
var number = weights.reduce(function (previous, current, index) {
var value = Math.random() * (current|0);
if (value > previous[0]) {
return [value, index];
}
return previous;
}, [Math.random() * (weights[0]|0), 0])[0];
使用索引作为整数,我们有:
由于在范围方面思考起来并不容易,或者如果您不想在手动N
之前指定所有值,您可以使用对象并通过指定键将其转换为数组{ {1}}等于length
,就像这样
N + 1
答案 2 :(得分:1)
您可以使用为每个可能的结果分配任意权重的想法,而无需创建与此一样大的数组。足以为每个可能的选择分配任意权重,然后将随机数转换为适当的结果。随机滚动的可能结果甚至不需要是连续的整数范围。
例如:
var weights = { 1: 4, 2: 3, 3: 1, 4: 1, 5: 1 }
// pre-processing; modifies weights!
var runningTotal = 0;
for (var number in weights) {
runningTotal += weights[number];
weights[number] = runningTotal;
}
// generation
var seed = Math.floor(Math.random() * runningTotal);
// conversion of seed to result based on weights
for (var number in weights) {
if (seed < weights[number]) {
console.log("result: " + number);
break;
}
}
请注意,上述内容仅作为说明性示例,而不是编写此代码的最佳方式。
<强> See it in action 强>
可以进一步概括这一点,以便您甚至不必提供明确指定每个可能结果的输入,但仍然适用相同的原则。
答案 3 :(得分:0)
由于数字Math.random()
介于0和1之间,您所要做的就是创建一个数组,其中的答案是1,2,3,4或5,例如
var px = [
{ answer: 1, pxi: 0.0, pxf:0.40 },
{ answer: 2, pxi: 0.40, pxf:0.60 },
{ answer: 3, pxi: 0.60, pxf:0.80 },
{ answer: 4, pxi: 0.80, pxf:0.90 },
{ answer: 5, pxi: 0.90, pxf:1 }
]
我们可以说r
是一个随机数字,所以如果r > pxi && r<=pxf
它会返回x
个答案。
所以,如果我足够清楚你可以看到这种方法重新提出1的可行性是40%,2是20%,3是20%,4是10%和5 10%,你可以很容易地改变概率通过改变范围pxi-pxf
来修改