【发布时间】:2021-06-25 09:51:38
【问题描述】:
这是我上一个问题的后续问题:Retrieve all possible combinations of ascending integers from sublists
解决这个问题的代码对于更大的列表来说真的很慢。 到目前为止,这是我的解决方案:
from typing import List, Tuple
from itertools import product, combinations
def is_ascending(t: tuple) -> bool:
return sorted(t) == list(t)
def get_ascending_combinations(a: List[List[int]]) -> List[Tuple, ...]]:
all_combs = []
add_comb = all_combs.append
input_length = len(a) + 1
for comb_length in range(2, input_length):
for main_comb in combinations(a, comb_length):
for comb in product(*main_comb):
if is_ascending(comb):
add_comb(comb)
return all_combs
example_list = [[0], [1, 4], [2]]
get_ascending_combinations(example_list)
>> [(0, 1), (0, 4), (0, 2), (1, 2), (0, 1, 2)]
example_list1 = [[0], [1, 4, 6], [2]]
get_ascending_combinations(example_list1)
>> [(0, 1), (0, 4), (0, 2), (1, 2), (0, 1, 2), (0, 6)]
example_list2 = [[0], [1, 4], [2], [5, 6]]
get_ascending_combinations(example_list2)
>> [(0, 1), (0, 4), (0, 2), (0, 5), (0, 6), (1, 2), (1, 5), (1, 6), (4, 5), (4, 6), (2, 5),
(2, 6), (0, 1, 2), (0, 1, 5), (0, 1, 6), (0, 4, 5), (0, 4, 6), (0, 2, 5), (0, 2, 6),
(1, 2, 5), (1, 2, 6), (0, 1, 2, 5), (0, 1, 2, 6)]
如示例中所示,它只能按升序进行组合。另一个限制是只允许与每个唯一子列表中的一个项目进行组合。
但是,此代码在较大的列表上确实很慢,因为可能的组合数量要大得多。如何制作一个更快的算法来做到这一点?请参阅下面的示例列表。
large_example = [[19, 67], [21, 43], [64], [47, 65, 69, 90], [48, 70], [0, 27, 63], [1], [2], [3],
[4, 53], [5], [6], [7, 57], [8, 58], [9], [10], [11, 82], [12, 37], [13],
[14, 77], [15], [16], [17], [18, 74], [20], [22], [23], [24, 30], [25], [26],
[28], [29], [31], [32], [33], [34], [35], [36], [38], [39], [40], [41], [78],
[79], [80], [46, 84], [85], [86], [87], [88], [89], [91], [50], [93]]
【问题讨论】:
-
每个子列表是否按升序排列?如果您利用已排序的子列表,那么长子列表的时间复杂度会更好,因此您不必将一个子列表的每个值与另一个子列表的每个值并列。如果您想使用长子列表并且子列表尚未排序,那应该是
get_ascending_combinations的第一阶段。 -
子列表是否互斥,所以如果一个整数出现在一个子列表中,则相同的整数不会出现在任何其他子列表中?
-
它并不是真正的升序,因为它代表了两个匹配文本的索引。子列表的顺序是标记在两个文本中出现的顺序
-
子列表因此不是互斥的,因为我想找到所有符合有效顺序的标记组合。这就是组合列表应该按升序排列的原因
标签: python python-3.x multithreading multiprocessing itertools