gpt4 book ai didi

javascript - 生成加权随机数

转载 作者:IT王子 更新时间:2023-10-29 03:04:57 24 4
gpt4 key购买 nike

我正在尝试设计一种(好的)方法来从一系列可能的数字中选择一个随机数,其中范围内的每个数字都被赋予了权重。简单来说:给定数字范围 (0,1,2) 选择一个数字,其中 0 有 80% 的概率被选中,1 有 10% 的概率,2 有 10% 的概率。

我上大学统计课已经大约 8 年了,所以你可以想象我现在还不知道正确的公式。

这是我想出的“廉价而肮脏”的方法。此解决方案使用 ColdFusion。你可以使用任何你喜欢的语言。我是一名程序员,我认为我可以处理它的移植。最终我的解决方案需要在 Groovy 中——我在 ColdFusion 中写了这个,因为它很容易在 CF 中快速编写/测试。

public function weightedRandom( Struct options ) {

var tempArr = [];

for( var o in arguments.options )
{
var weight = arguments.options[ o ] * 10;
for ( var i = 1; i<= weight; i++ )
{
arrayAppend( tempArr, o );
}
}
return tempArr[ randRange( 1, arrayLen( tempArr ) ) ];
}

// test it
opts = { 0=.8, 1=.1, 2=.1 };

for( x = 1; x<=10; x++ )
{
writeDump( weightedRandom( opts ) );
}

我正在寻找更好的解决方案,请提出改进​​或替代方案的建议。

最佳答案

Rejection sampling (例如在您的解决方案中)是首先想到的,您可以构建一个查找表,其中包含按权重分布填充的元素,然后在表中选择一个随机位置并将其返回。作为一个实现选择,我会创建一个高阶函数,它接受一个规范并返回一个函数,该函数根据规范中的分布返回值,这样您就可以避免为每次调用构建表。缺点是构建表的算法性能与项目数量成线性关系,并且对于大型规范(或那些具有非常小或精确权重的成员,例如 {0:0.99999, 1 :0.00001})。好处是选择一个值有恒定的时间,如果性能很关键,这可能是可取的。在 JavaScript 中:

function weightedRand(spec) {
var i, j, table=[];
for (i in spec) {
// The constant 10 below should be computed based on the
// weights in the spec for a correct and optimal table size.
// E.g. the spec {0:0.999, 1:0.001} will break this impl.
for (j=0; j<spec[i]*10; j++) {
table.push(i);
}
}
return function() {
return table[Math.floor(Math.random() * table.length)];
}
}
var rand012 = weightedRand({0:0.8, 1:0.1, 2:0.1});
rand012(); // random in distribution...

另一种策略是在 [0,1) 中选择一个随机数,并迭代权重规范,对权重求和,如果随机数小于总和,则返回关联值。当然,这假设权重之和为 1。该解决方案没有前期成本,但平均算法性能与规范中的条目数呈线性关系。例如,在 JavaScript 中:

function weightedRand2(spec) {
var i, sum=0, r=Math.random();
for (i in spec) {
sum += spec[i];
if (r <= sum) return i;
}
}
weightedRand2({0:0.8, 1:0.1, 2:0.1}); // random in distribution...

关于javascript - 生成加权随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8435183/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com