按累计大小对项目列表进行分组,并限制组的大小

时间:2015-11-22 22:49:08

标签: python algorithm

我正试图想出一种将[name, size]对列表组合在一起的方法。我们的想法是将它们组合在一起,以便每个组尽可能接近maximum_group_size,但不会中断maximum_group_length截止。

例如,如果maximum_group_size = 10maximum_group_length = 3,则可以将以下简单数据集分组:

data = [['A', 3], ['B', 6], ['C', 7], ['D', 1]]
grouped: [[['A', 3], ['B', 6]], [['C', 7], ['D', 1]]]

但是这个数据集最终会成为:

data = [['A', 1], ['B', 1], ['C', 1], ['D', 1]]
grouped: [[['A', 1], ['B', 1], ['C', 1]], ['D', 1]]]

输入数据未排序,但可以轻松排序。我的直觉不是这样做,因为排序会导致最多的群体不满。

我怎么能(漂亮地)这样做呢?我目前的实施不是很优雅:

def group_references(sam_handle, num_bases=10 ** 7, max_seqs=100):
    """
    Group up references by num_bases, unless that exceeds max_seqs.
    """
    name_iter = itertools.izip(*[sam_handle.references, sam_handle.lengths])
    name, size = name_iter.next()
    this_bin = [[name, size]]
    bin_base_count = size
    num_seqs = 1
    for name, size in name_iter:
        bin_base_count += size
        num_seqs += 1
        if bin_base_count >= num_bases or num_seqs > max_seqs:
            yield this_bin
            this_bin = [[name, size]]
            bin_base_count = size
            num_seqs = 1
        else:
            this_bin.append([name, size])

2 个答案:

答案 0 :(得分:2)

你可以证明,如果你能在多项式时间内最优地求解,你也可以在多项式时间内解决背包问题,这是不可能的。因此,解是非多项式的。

无论如何,我建议查看背包问题的各种近似解决方案,并选择最适合您案例的解决方案。

答案 1 :(得分:0)

您的问题是Bin packing problemPacking problem

看一下similar question,你可以在python中找到一段代码。