python - 带权重的位掩码

标签 python algorithm language-agnostic

我有以下对:

pairs = [(1,9),(5,5),(6,4),(2,8)]

从这对元素中我只能取出一个元素。我需要生成 n 个具有最小总和的二进制掩码组合列表,其中 0 表示第一个元素,1 表示第二个元素。

如果 n == 5,则提供示例的输出:
[0,0,1,0], [0,1,1,0], [0,0,0,0], [0,1,0,0], [0,0,1, 1]

是这样的Knapsack Problem ?执行此操作的最佳算法是什么?

最佳答案

下面代码背后的想法是枚举排序的组合 递归地(好吧,不使用递归)对列表的尾部, 然后在使用较小的组合之间进行排序合并 第一对的元素以及使用较大者的组合 第一对的元素。使用最小化空间需求 生成器(通常应按元素数量的顺序排列) 你拿)。

import collections
import itertools


def extend_sorted(pair, sequence):
    argmin_pair = min(range(2), key=pair.__getitem__)
    min_pair = pair[argmin_pair]
    argmax_pair = 1 - argmin_pair
    max_pair = pair[argmax_pair]
    buffer = collections.deque()
    for sub_combo, sub_total in sequence:
        while buffer and buffer[0][1] < min_pair + sub_total:
            yield buffer.popleft()
        yield ([argmin_pair] + sub_combo, min_pair + sub_total)
        buffer.append(([argmax_pair] + sub_combo, max_pair + sub_total))
    while buffer:
        yield buffer.popleft()


def enumerate_least_sums(pairs):
    sequence = [([], 0)]
    for pair in reversed(pairs):
        sequence = extend_sorted(pair, sequence)
    for combo, total in sequence:
        yield combo


if __name__ == "__main__":
    print(*itertools.islice(enumerate_least_sums([(1, 9), (5, 5), (6, 4), (2, 8)]), 5))

输出:

[0, 0, 1, 0] [0, 1, 1, 0] [0, 0, 0, 0] [0, 1, 0, 0] [0, 0, 1, 1]

关于python - 带权重的位掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73375106/

相关文章:

python - 内置的 iter() 有什么意义?

algorithm - 如何将普通二叉树转换为 "smarter"二叉树,其中每个节点都知道其父节点、子节点总数和级别?

language-agnostic - 使用栈实现数组

python - 如何获得与python的最短匹配(复杂的非贪婪模式)

python - Celery是否使用链和组组合的结果后端?

Java算法

python - 无法正确识别字母

c - 找到一对数字的4次方等于输入数字

language-agnostic - 什么时候使用 do-while 合适?

javascript - 字符转义: from Python string literal to JSON and then to HTML