将值拆分为类似分布的均匀大小的组

时间:2018-03-21 18:55:05

标签: algorithm grouping

给定一个标量值列表,我们如何将列表拆分为K个均匀大小的组,以使这些组具有相似的分布?请注意,简单性比效率更受青睐。

我目前正在做:

sort values
create K empty groups: group_1, ... group_k
while values is not empty:
    for group in groups:
        group.add(values.pop())
        if values is empty:
            break

2 个答案:

答案 0 :(得分:2)

这是一种(以某种方式)均匀分配值的方法。 我们假设您的标量数组A的大小为nnk的倍数,以使其更简单。 一种方法是:

sort(A)
d = n/k
g = 0
for i from 0 to d-1 do {
  for j from 0 to k-1 do {
    group[(j+g) % k].add(A[k*i + j])
  }
  g ++
}

然后,您将前k个元素添加到组1, ..., k,k跟随组2, ..., k, 1,然后3, ...k, 1, 2等。

如果k² > n,则不能正常工作,在这种情况下,您不应将g增加1,而应增加接近k/d的值。如果k几乎为n,则此算法变得毫无用处。

如果某些极端值存在于A中,这绝对不能保证标量的均匀分布。但是在A本身在某种程度上分布良好的情况下,n > k²,那么它会以某种方式在k组之间分配值。

一旦O(n)被排序,它至少具有在A中运行的优势。

答案 1 :(得分:2)

这是对@ m.raynal提出的一个变体,即使n只是k的一个相当小的倍数,它也能很好地运作。

  1. 将元素从最小到最大排序。
  2. 创建k个空组。
  3. 将它们放入从最少元素到最多元素排序的Priority Queue中,然后从最小值到最小值。 (因此下一个元素总是具有最少元素的所有元素中最大的元素。)
  4. 对于每个元素,从优先级队列中取出一个组,添加该元素,将该组放回优先级队列。
  5. 实际上,这意味着第一个k元素随机转到组,下一个k元素按相反的顺序排列。然后它变得聪明,保持平衡。

    根据您的应用,底部两个值可预测地相隔很远的事实可能是一个问题。如果是这种情况,那么你可以通过" mid out"来解决这个问题。但是这个方案要复杂得多。