在Python中按其元素的总和对组合进行排序

时间:2017-04-27 15:50:35

标签: python sorting combinations itertools

我在Python中有一个庞大的整数列表(1000000+个元素),但为了简单起见,我将用一个例子来说明我需要的东西。让我们假设我有这个清单:

A = [1,2,3,4,100]

现在我想获得该列表的所有组合(大小3),所以我使用itertools。

combinations = itertools.combinations(A,3)

但我的问题是,这将以字典顺序返回组合:

(1,2,3)
(1,2,4)
(1,2,100)
(1,3,4)

等等。

我希望按照元素总和排序。那将是:

(1,2,3)总和6, (1,2,4)总和7, (1,3,4)总和8,

等等。

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:0)

这里要考虑的关键是no.of组合真的很大〜(1000000)^^ 3 因此,任何带有O(NlogN)的排序算法都会很糟糕。我们需要O(N)中的东西。

我们可以尝试创建一个SortedDictionary(sorteddict)或使用像memcache这样的标准外部哈希实现来存储组合 {sum:[tuple1,tuple2]}。此操作的复杂性为~O(N)

然后,创建一个新列表,循环缓存以及所有值。复杂性将再次为O(N)。

总的来说,我们将有O(2N),它比O(NLogN)有效。希望这会有所帮助!

答案 1 :(得分:0)

有序组合太大而无法放入内存

每次拍摄1,000件物品的组合数量为166,666,166,667,000,000。这太大了,不适合记忆,太大而不能排序,太大而不能在合理的时间内循环。

有关延迟生成这些组合的方法,请参阅Donald Knuth关于组合算法的分册中的"GENERATING ALL COMBINATIONS"

可以适合内存的有序组合

只要组合的数量合理,最直接的方法是直接按组合对组合进行排序:

>>> import itertools
>>> import pprint

>>> A = [1, 2, 3, 4, 100]
>>> combinations = sorted(itertools.combinations(A, 3), key=sum)
>>> pprint.pprint(combinations)
[(1, 2, 3),
 (1, 2, 4),
 (1, 3, 4),
 (2, 3, 4),
 (1, 2, 100),
 (1, 3, 100),
 (1, 4, 100),
 (2, 3, 100),
 (2, 4, 100),
 (3, 4, 100)]

该技术使用sum()作为key-functionsorted()

弥合两个世界

nCr大于实际可以枚举的值时,通过从列表 A 中删除较大的元素来减少问题是有意义的,直到总和变得足够大以包含这些值