我有一个非常大的列表,包含大约10,000个元素,每个元素是一个大到50亿的整数。我想从最大大小为10,000个元素的数组的每个可能的大小'k'(由用户给出)子集中找到最大元素的总和。我想到的唯一解决方案是生成每个子集(使用itertools)并找到其最大元素。但这需要花费大量时间!什么是解决这个问题的pythonic方式?
答案 0 :(得分:6)
不要使用python,首先使用数学。这是一个组合问题:如果您有 n 数组的数组S
( n 大),并生成所有可能的大小 k <的子集/ em>,您想要计算子集的最大元素的总和。
假设数字都是不同的(尽管它们也不同),你可以精确计算每个数字出现在一个子集中的频率,并从那里开始,而不必实际构建一个子集。你应该把它带到math.stackexchange.com
,他们已经把你整理好了。这是它,但没有很好的数学符号:
按递增顺序对数组进行排序,让S_1
为最小(第一个)数字,
S_2
下一个最小的,依此类推。 (注意:从1开始索引)。
S_n
,最大的元素,显然是任何子集的最大元素
它是其中的一部分,并且确实有(n-1 choose k-1)
个这样的子集。
在不包含S_n的子集中,有(n-2 choose k-1)
包含S_{n-1}
的子集,其中它是最大的元素。
继续此操作,直到S_k
k-th
最小的数字
(从最小的数量开始计算),这将是最大的一个
子集:(k-1 choose k-1) = 1
。较小的数字(S_1
至S_{k-1}
)
永远不会是最大的:每组k
元素都包含一些内容
大。
总结以上(n-k+1 terms)
,你的答案是:
S_n*(n-1 choose k-1) + S_{n-1}*(n-2 choose k-1) + ... + S_k*(k-1 choose k-1)
将术语从最小写到最大,这只是总和
Sum(i=k..n) S_i * (i-1 choose k-1)
如果我们在math.stackexchange上你会得到正确的数学符号,但你明白了。