【发布时间】:2019-11-14 06:45:13
【问题描述】:
在 Ruby 中,如何对数组进行排序,使其项目(也包括数组)按长度大小排列,而不是简单地按长度升序/降序排序。
我想让数组项均匀分布,以便有些项包含大量对象与较小的数组混合。
例如,我有一个包含数组项的数组,其中包含comment 中显示的对象数。为了清楚起见,我将它们分成几块并计算了它们的总大小(请参阅下面的动机)。
[
# chunk 1, inner total length 5
[{...}], # 2
[{...}], # 1
[{...}], # 1
[{...}], # 1
# chunk 2, inner total length 11
[{...}], # 2
[{...}], # 2
[{...}], # 3
[{...}], # 4
# chunk 3, inner total length 9
[{...}], # 3
[{...}], # 3
[{...}], # 1
[{...}], # 2
# chunk 4, inner total length 15
[{...}], # 4
[{...}], # 3
[{...}], # 4
[{...}], # 4
]
我想排列数组,使其看起来更像下面。注意:此示例将它们从最小到最大 (1..4) 排序,但这不是必需的。我只想将它们分块,以便内部数组累积长度具有可比性。
[
# chunk 1, inner total length 10
[{...}], # 1
[{...}], # 2
[{...}], # 3
[{...}], # 4
# chunk 2, inner total length 10
[{...}], # 1
[{...}], # 2
[{...}], # 3
[{...}], # 4
# chunk 3, inner total length 10
[{...}], # 1
[{...}], # 2
[{...}], # 3
[{...}], # 4
# chunk 4, inner total length 10
[{...}], # 1
[{...}], # 2
[{...}], # 3
[{...}], # 4
]
我这样做的动机是分割外部数组,这样我就可以并行处理内部数组。我不希望其中一个并行进程获得一小块,而另一个进程获得一块非常大的块。
注意:我知道我将有 4 个并行进程,这可能有助于告知如何排列数组中的块。谢谢!
【问题讨论】:
-
非常有趣的问题,尽管我担心您可能从并行处理每个分布式块中获得的任何收益都会被分配所需的初始排序算法所权衡。
-
不能均匀排序的数据怎么办?假设我有 4 个长度为 1、2、4 和 4 的数组。它们不能均匀分组。
-
另外,根据您的参数,(根据我上面的评论,假设存在解决方案)这个问题是 NP-Complete。考虑您希望将大型数据集组织成仅两个块的情况。 Bam,你有partition problem。也就是说,对于某些输入,计算它可能需要很长时间。
-
作为建议,启发式方法可能会更好。您可以对所有数组进行分块并按数组长度排序。然后遍历块,将带有
index % 4 == 0的项目分配给第一个进程,index % 4 == 1分配给第二个进程,index % 4 == 2分配给第三个进程,index % 4 == 3分配给第四个进程。这不会提供完美的解决方案,但会大致正确。它的好处是更简单,并且初始排序更快。 -
你也可以通过设置四个worker,然后让master给每个worker分配一份工作来避免预分块;当一个工人完成工作时,它会得到下一个可用的工作。这意味着一些工人可能会做几份大工作,而另一些工人可能会做更多的小工作,最终还是有点平(直到一份工作的差异)。当作业长度无法从输入中预测时,这也适用。例如,
parallelgem 可以自动为您完成。
标签: arrays ruby sorting parallel-processing