当前位置: 首页 > 知识库问答 >
问题:

从给定的数字求和到给定值的序列?

苏波涛
2023-03-14

给定一组整数(正数或负数),我怎样才能找到一个和给定值相加的数字序列?

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

这就像子集和问题(http://en.wikipedia.org/wiki/Subset_sum)但就我而言,数字可以重复使用。

这也有点像分区问题(找到所有可能的子集,求和到一个给定的数字),但在我的例子中有负值。

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

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)

共有2个答案

郝昊东
2023-03-14

因为它显然至少是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 }

你可以用任何解算器来解。

蒯嘉赐
2023-03-14

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

考虑到这个问题是NP完全问题,我认为您应该专注于改进当前的算法,或者用更快的语言(如C)重写它。然后您可以从Python调用您的C代码

 类似资料:
  • 给定一个2d数组,我需要返回一个具有路径的矩阵,该路径递归地求和到给定的数字。 路径矩阵应为零,但总计为给定数字的路径除外,该路径将标记为1。 路径只能在 我尝试过所有的可能性,首先检查我是否已经去过下一个街区。 问题是在一些迭代之后,它会停止,并且不会返回并再次将块清除为0。 给定 在通话中 我以为算法会回来 我得到 相反 调用paintPath(mat1400,path,0,0);我想 或 问

  • 我正在寻找以下问题的答案。 给定一组整数(无重复项)和一个和,找出集合元素的所有可能组合,并求和。解的顺序并不重要(解{2,2,3}和{3,2,2}是相等的)。 请注意,最终组合不需要是集合,因为它可以包含重复。 示例:集合{2,3,5}和10 结果:{2, 2, 2, 2, 2},{2,2,3,3},{2,3,5},{5,5} 我已经研究过子集和问题以及硬币兑换问题,但不能使它们适应我的需要。我

  • 问题陈述如下: 当帖子说解决方案对负数不起作用时,它指的是哪些输入情况?

  • 我试图从表示数字的int数组生成所有可能的数字。 例如,我得到以下结果。 例如,arr=new int[]{1,2,3},我得到以下结果。 1 2 3 11 21 31 12 22 32 13 23 33 111 211 311 121 221 321 131 231 331 112 212 312 122 222 322 132 232 332 113 213 313 123 223 323 1

  • 我想找到一组素数的最小集合,它可以和一个给定的值,例如9=7+2(而不是3+3+3)。 我已经使用eratosthens筛生成了一个数组素数 我正在按降序遍历数组,以获得数组中小于或等于给定数的最大素数。如果数字是奇数,这很有效。但对于偶数(例如122=113+7+2,但122=109+13)则失败。

  • 我在Scala中做了一个问题,这是任务语句的摘要: 上述示例的输出: 1 2 3 -1 第一行是数组长度,第二行是整数数组(0 以下是我尝试的:选择的元素并不重要。所以我先对给定整数的列表排序最大。然后我选择了第一个元素,检查它是否大于S,如果不大于S,我也选择了第二个元素,依此类推,直到总和大于或等于S。 我的代码(Scala):