Algorithm 如何找出哪些小计构成一个总数?

Algorithm 如何找出哪些小计构成一个总数?,algorithm,sum,subtotal,Algorithm,Sum,Subtotal,我需要在列表中找到数字,这些数字构成了一个特定的总数: Sum: 500 Subtotals: 10 490 20 5 5 In the end I need: {10 490, 490 5 5} 你怎么称呼这类问题?是否有有效的算法来解决它?这是一个NP完全问题,即没有已知的有效算法。这是一个NP完全问题,即没有已知的有效算法 这不是背包问题 在最坏的情况下,对于N个小计,可能有O(2^N)个解,因此在最坏的情况下,任何算法都不会比这更好(因此,问题根本不属于NP类) 让我们假设小计数组

我需要在列表中找到数字,这些数字构成了一个特定的总数:

Sum: 500

Subtotals: 10 490 20 5 5

In the end I need: {10 490, 490 5 5}
你怎么称呼这类问题?是否有有效的算法来解决它?

这是一个NP完全问题,即没有已知的有效算法。

这是一个NP完全问题,即没有已知的有效算法

  • 这不是背包问题
  • 在最坏的情况下,对于N个小计,可能有O(2^N)个解,因此在最坏的情况下,任何算法都不会比这更好(因此,问题根本不属于NP类) 让我们假设小计数组中没有非正元素,并且任何元素都不大于总和。我们可以对小计数组进行排序,然后构建尾和数组,最后加0。在您的示例中,它将如下所示:

    Subtotals:   (490, 20, 10,  5, 5)  
    PartialSums: (530, 40, 20, 10, 5, 0)
    
    现在,对于任何“余额”S、位置i和“当前列表”L,我们都有问题E(S、i、L):
    E(0,i,L)=(打印L)。
    E(S,i,L)|(PartialSums[i] E(S,i,L)=E(S,i+1,L),E(S-小计[i],j,L | |小计[i]),其中j是小计第一个元素的索引,小于或等于(S-小计[i])或i+1,以较大者为准。
    我们的问题是E(和,0,{})

    当然,重复也有问题(如果列表中还有490个数字,此算法将输出4个解决方案)。如果这不是您所需要的,那么使用成对数组(值、多重性)可能会有所帮助

    <强> P.S.如果问题的规模足够小,你也可以考虑动态规划:

  • 从集合{0}开始。创建大小等于小计数组的集合数组
  • 对于每个小计,通过添加小计值从上一个集合创建一个新集合。删除大于总和的所有元素。将其与上一个集合合并(它本质上是所有可能的和的集合)
  • 如果最后一组中没有求和,那么就没有解。否则,将解决方案从Sum回溯到0,检查上一个集合是否包含[value]和[value subtotal]。
    例如:

    (10490,20,5,5)

  • 设置:

    从上一个集合中[500-5]在上一个集合中[495-5]在上一个集合中[490-20]不在上一个集合中([490]是),[490-490]是0,结果是答案{5,5490}

  • 这不是背包问题
  • 在最坏的情况下,对于N个小计,可能有O(2^N)个解,因此在最坏的情况下,任何算法都不会比这更好(因此,问题根本不属于NP类) 让我们假设小计数组中没有非正元素,并且任何元素都不大于总和。我们可以对小计数组进行排序,然后构建尾和数组,最后加0。在您的示例中,它将如下所示:

    Subtotals:   (490, 20, 10,  5, 5)  
    PartialSums: (530, 40, 20, 10, 5, 0)
    
    现在,对于任何“余额”S、位置i和“当前列表”L,我们都有问题E(S、i、L):
    E(0,i,L)=(打印L)。
    E(S,i,L)|(PartialSums[i] E(S,i,L)=E(S,i+1,L),E(S-小计[i],j,L | |小计[i]),其中j是小计第一个元素的索引,小于或等于(S-小计[i])或i+1,以较大者为准。
    我们的问题是E(和,0,{})

    当然,重复也有问题(如果列表中还有490个数字,此算法将输出4个解决方案)。如果这不是您所需要的,那么使用成对数组(值、多重性)可能会有所帮助

    <强> P.S.如果问题的规模足够小,你也可以考虑动态规划:

  • 从集合{0}开始。创建大小等于小计数组的集合数组
  • 对于每个小计,通过添加小计值从上一个集合创建一个新集合。删除大于总和的所有元素。将其与上一个集合合并(它本质上是所有可能的和的集合)
  • 如果最后一组中没有求和,那么就没有解。否则,将解决方案从Sum回溯到0,检查上一个集合是否包含[value]和[value subtotal]。
    例如:

    (10490,20,5,5)

  • 设置:


    从上一个集合中的[500-5],[495-5]在上一个集合中,[490-20]不在上一个集合中([490]是),[490-490]是0,结果是答案{5,5490}.

    你试过什么吗?看起来像a。我正在看这篇文章:会有负数吗?你试过什么吗?看起来像a。我正在看这篇文章:会有负数吗?我无法从根本上理解你的解决方案是什么,但我确信最初的问题是背包问题。对于原始列表中的n个元素,这些元素有2n个子集,您需要识别其和正好是给定整数的那些元素。找到这样一个子集已经很难了。首先,背包问题需要两组数字,权重和成本。第二:背包问题是关于发现是否存在一个适合背包的布局,并且成本高于给定的N。因此,背包问题的假设解不容易转化为该问题的解,它们是不同的问题。第三:背包问题是NP完全问题,这意味着它与SAT问题“等价”。Kiril提出的问题不是NP,因为在最坏的情况下,它不能在多项式时间内解决(具有非多项式大小的输出)。其中列出了权重等于成本的情况,并注明“如果每个项目的利润和权重相同,我们得到子集和问题。”子集问题也是NP完全问题。是的,列举任何问题的所有解决方案,这些问题的数量可以是指数级的,这在NP中不是一个问题。当我写“这是一个背包问题”时,我把它简化了。我想我应该写下“决策版本已经是一个背包式的NP完全问题,通常被称为子集和”。好吧,仍然有一些不同。首先,w