我在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,
等等。
我怎样才能做到这一点?
答案 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-function的sorted()。
当nCr大于实际可以枚举的值时,通过从列表 A 中删除较大的元素来减少问题是有意义的,直到总和变得足够大以包含这些值