基于权重在N个桶之间分配一组元素

distrubute a set of elements between N buckets based on weights

本文关键字:分配 之间 元素 一组 于权重 权重      更新时间:2023-10-16

给定N个桶和一些元素E1(W1)E2(W2)。我想根据元素Ei的权重Wi-在元素Ei之间分配N个桶

For example N = 20, W1 = 5 W2 = 5 W3 = 10 so
E1_buckets = 20*(5/20) = 5
E2_buckets = 20*(5/20) = 5
E3_buckets = 20*(10/20) = 10

I必须使各个桶(5+5+10=20)的总和达到N。我想做一些类似的事情

bucket[i] = round(N*(W[i]/TOT_WGT) where W[i] = element weight, and TOT_WGT = sum of weights W[i]

然而,我似乎可能会因为浮点数的表示不精确而遇到错误。浮点运算是否可以保证桶的总和始终为N?

另一种方法是总是发言,并将多余的部分分配给一些随机元素

bucket[i] = floor(N*(W[i]/TOT_WGT)
bucket[k] += (N-sum_of_buckets)

虽然它不能保证完美的加权,但我确实得到了桶和N的总和。有什么想法吗,我是不是错过了什么,有一个简单的方法可以做到这一点?

您可以计算前i个元素中的bucket数量,然后减去前i-1个元素中bucket的数量,而不是计算元素i中bucket数量。

在这种情况下,前i个元素中的桶的数量可以是四舍五入的(N*SUM_k_up_ti(W[k])/TOT_WGT)。在这种情况下,所有存储桶中的元素数量都是四舍五入的(N*TOT_WGT/TOT_WGT),很可能总和为N,并且在任何情况下都可以用N替换,并且可以保证存储桶的总和为N。

最好的方法是不使用bin的宽度来表示bin。你试图表示一个连续的区间,而通过对齐子区间的并集来实现这一点——至少可以说是很棘手的。

相反,计算内部分隔符的位置(在您的示例中为{5,10}),然后将您的桶表示为端点对(在示例中端点为{0,5,10,20})。每当您需要一个bin的宽度时,返回该bin的两个端点之间的差值。是的,垃圾箱的宽度可能与权重相差一点,但如果你的应用程序对这个错误很敏感,你真的应该使用精确的数字类型。