从给定的数字中找到一个序列,其总和为给定的值?

2024-05-21 02:38:29 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一组整数(正的或负的),我怎样才能找到这些数的和到给定值的序列?在

示例:给定一个数字列表[4,-16, 9, 33],我需要求和17。我可以选择序列[4, 4, 9](数字可以重用)或[-16, 33]。我想找到一种有效的方法来缩短序列的长度。在

它类似于Subset Sum Problemhttp://en.wikipedia.org/wiki/Subset_sum),但在我的例子中,数字可以重用。在

它也有点像分区问题(Find all possible subsets that sum up to a given number),但在我的例子中有负值。在

我当前的贪心算法如下。在每个循环中,我将尝试找到一个使当前和与目标和之间的差最小化的数字。在

integers = [-2298478782, 1527301251, 4, 4078748803, 3388759435,
        1583071281, 2214591602, 1528349827, -12, 59460983,
        -939524100, -1, 2315255807]
target_sum = 1997393191

difference = target_sum
chain = list()
while difference != 0:
    min_abs_difference = abs(difference)
    next_int = 0
    found = False
    for i in integers:
        new_abs_diff = abs(i+difference)
        if new_abs_diff < min_abs_difference:
            found = True
            next_int = i
            min_abs_difference = new_abs_diff
    if not found:
        print(difference)
        print(chain)
        print("Cannot find an integer that makes difference smaller")
        break
    difference += next_int
    chain.append(next_int)
print(chain)

Tags: chainnewdiff序列数字absmin例子
2条回答

因为它显然至少是NP完全问题,你可以把它看作一个混合整数线性规划问题。在

Minimize summation( Xi ) // Xi = number of times the array element Ai is used.
Subject To
     summation( Ai*Xi ) = S.
     Xi >= 0 { Xi are all integers }

您可以使用任何解算器解决它。在

很可能没有一个快速算法能给出一个最优解。子集和问题是NP完全的,这个问题比你的问题简单(因为你允许重复使用数字)。在

考虑到这个问题是NP完全的,我认为您应该集中精力改进当前的算法,或者用更快的语言(如C)重写它。在

相关问题 更多 >