问题描述
我有几个排序的整数列表,长度可能不同,元素可能重复。我想编写一个生成组合的生成器,每个列表中的一个元素,按组合总和的降序排列。所以,如果我的列表是:
l_1 = [10,9,8,5,2]
l_2 = [15,7]
l_3 = [8,4,2,2]
我想回来:
(10,15,8),# sum=33
(9,# sum=32
(8,# sum=31
(10,4),# sum=29
(9,# sum=28
(5,# sum=28
等等。当多个组合产生相同的总和时,我不关心组合返回的顺序(例如,上面的最后两行可以颠倒而不会产生任何后果)。
我知道我可以使用 itertools.product
然后对结果进行排序,但我的列表可能很长,而且我可能有很多,并且在迭代总和时,我最终会达到停止点,因此无需将所有内容都存储在内存中。速度很重要,但我不确定像这样的事情的最佳时间复杂度(我不是很精通那种东西)。
编辑:到目前为止,我最好的解决方案是结合我见过的其他一些 SO 帖子。这个想法是最大的总和是每个列表中的第 0 个元素。所以指针在第一次迭代时是 (0,0)。然后,下一个最高的总和必须是 (1,0) 或 (0,1,1),因此将它们添加到优先级等于对应于以下元素的总和的 heapq那些指针。跟踪“可见”指针以避免重复。
import heapq
def best_search(*sequences):
# Assumes sequences are passed pre-sorted from high to low (reverse order).
# If not,sort them here.
num_seqs = len(sequences)
start = (0,) * num_seqs
queue = [(0,start)]
seen = set(start)
while queue:
priority,pointers = heapq.heappop(queue)
yield pointers
for i in range(num_seqs):
if pointers[i] + 1 < len(sequences[i]):
new_pointers = list(pointers)
new_pointers[i] += 1
new_pointers_t = tuple(new_pointers)
if new_pointers_t not in seen:
seen.add(new_pointers_t)
priority = sum(seq[pointer] for seq,pointer in zip(sequences,new_pointers_t))
heapq.heappush(queue,(-priority,new_pointers_t))
它对前几百万个组合效果很好,但最终运行得很慢;我怀疑这是因为 seen
集变得非常大,并且针对该集检查新的可能的指针元组非常耗时。任何改进表示赞赏!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)