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

时间:2013-11-23 01:01:19

标签: c++ algorithm

给定N个桶和一些元素E1(W1)E2(W2)。我想基于它们的权重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

必须将各个桶(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的桶。 任何想法,我错过了什么,有一个可能的简单方法来做到这一点?

2 个答案:

答案 0 :(得分:1)

不是计算元素i中的桶数,而是可以计算前i个元素中的桶数,然后在第一个i-1元素中减去桶的数量,以获得元素中的桶数岛

在这种情况下,第一个i元素中的桶的数量可以是round(N * SUM_k_up_to_i(W [k])/ TOT_WGT)。在这种情况下,所有桶中的元素数量将是圆的(N * TOT_WGT / TOT_WGT),它很可能总和为N - 并且在任何情况下都可以用N替换,并且保证桶的总和将是N。

答案 1 :(得分:1)

最好的方法是不使用宽度表示bin。你试图表示一个连续的区间,并且通过将子区间的联合对齐〜恰到好处〜来做到这一点,至少可以说是棘手的。

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