在文本文件中的 50 个数字中找到 10 个数字的最低覆盖率

问题描述

所以基本上我有一个包含 50 个覆盖率的文本文件,从数字 0 开始大约波动(加减)1*10^{-6}。我试图从数据集中找到 10 个数字,这给了我最接近数字 0 的数字之和。 有没有办法在 python 中通过迭代所有数字并从 50 个数字中找到 10 个数字来做到这一点给我最接近零的数字?希望这个问题有意义:/

解决方法

使用 itertools.combinations,应该不到一个小时:

min(combinations(numbers,10),key=lambda c: abs(sum(c)))

更快的想法:将数字分成两组 A 和 B,每组 25 个数字。取 A 中的 i 个数字和 B 中的 10-i 个数字(尝试从 0 到 10 的所有 i)。

例如,当从 A 中取出 3 个数字和从 B 中取出 7 个数字时,A 中有 25C3=2300 种组合,B 中有 25C7=480700 种组合。将 B 中的组合按总和排序,然后遍历 A 中的组合并对其进行二分查找求和 B 中的组合求和,找到 B 中的最佳组合与 A 中的组合相结合。

对于 i>5,即,当您从 A 中获取的数字多于从 B 中获取的数字,因此从 A 中获取的组合多于从 B 中获取的组合,请对来自 A 的数字进行排序,然后对来自 B 的数字进行排序,并在来自 A 的数字中进行二分查找。

每个组合需要更多的努力,但总体而言组合要少得多,所以我认为它会更快:

>>> from math import comb

>>> comb(50,10)
10272278170

>>> sum(comb(25,i) + comb(25,10-i) for i in range(11))
14239032

>>> 10272278170 / 14239032
721.4168891537009

带有附加总和的组合的创建和排序应该花费大部分时间。为 i

from random import random
from itertools import combinations

numbers = [random() * 2e-6 - 1e-6 for _ in range(50)]

B = numbers[25:]

for i in range(6):
    combs = [(sum(comb),comb) for comb in combinations(B,10-i)]
    combs.sort()

总的来说,我认为这个解决方案大约需要一分钟。

或者我们可以先找到最好的和,然后在最后重建产生那个和的组合。以下大约需要 4 秒,因此整个真正的解决方案可能需要大约 10 秒:

for i in range(6):
    sums = list(map(sum,combinations(B,10-i)))
    sums.sort()

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...