【问题标题】:efficient methods to do summation求和的有效方法
【发布时间】:2012-05-10 02:56:45
【问题描述】:

是否有任何有效的技术来进行以下求和?

给定一个包含 n 个整数 A={X1,X2,…,Xn} 的有限集 A,其中 Xi 是一个整数。现在有 An 个子集,用 A1, A2, ... , An 表示。我们要计算每个子集的总和。有没有一些有效的技术?

(请注意,n 通常大于 A 的所有子集的平均大小。)

例如,如果A={1,2,3,4,5,6,7,9}A1={1,3,4,5} em> , A2={2,3,4}A3= ... 。计算 A1A2 总和的简单方法需要 5 个 Flops 进行加法:

总和(A1)=1+3+4+5=13

总和(A2)=2+3+4=9

...

现在,如果先计算 3+4,然后记录它的结果 7,我们只需要 3 个 Flops 来进行加法:

总和(A1)=1+7+5=13

总和(A2)=2+7=9

...

一般情况下呢?有没有什么有效的方法可以加快计算速度?谢谢!

【问题讨论】:

  • n 可以有多少近似值?
  • 答案可能取决于以下因素:您的两个“n”(A 中的元素数和子集数)真的相等吗?它们有多大?子集有多大?你会用“相同的子集”重复做同样的事情吗? (注意:显然 A 并不是真正的 set 而是一个 sequence 并且大概每个 Aj 都由一个A 中的一堆索引。)
  • n 非常大,而 A 的子集的大小远小于 n
  • 是的,两个“n”相等,n大于A子集的平均大小。
  • 我们是否假设由于某种原因在这个理论系统上添加非常昂贵?因为否则你会发现任何“聪明”的算法都需要更多的处理而不是简单地添加子集。

标签: c arrays algorithm


【解决方案1】:

对于某些子集的选择,如果您不介意进行一些(可能很昂贵)的预计算,但不是所有的都可以加快计算速度。例如,假设您的子集是 {1,2}, {2,3}, {3,4}, {4,5}, ..., {n-1,n}, {n,1};那么幼稚的方法对每个子集使用一个算术运算,显然你不能做得比这更好。另一方面,如果您的子集是 {1}, {1,2}, {1,2,3}, {1,2,3,4}, ..., {1,2,..., n} 那么你可以使用 n-1 算术运算,而幼稚的方法要糟糕得多。

这是进行预计算的一种方法。它并不总能找到最佳结果。对于每对子集,将转换成本定义为 min(对称差异的大小,Y - 1 的大小)。 (X 和 Y 的对称差是 X 或 Y 中的一组事物,但不是两者。)因此,转换成本是计算 Y 元素之和所需的算术运算次数,给定X的。将空集添加到子集列表中,并使用 Edmonds 算法 (http://en.wikipedia.org/wiki/Edmonds%27_algorithm) 或更快但更复杂的变体之一计算最小成本有向生成树那个主题。现在确保当你的生成树有一条边 X -> Y 时,你在 Y 之前计算 X。(这是一种“拓扑排序”,可以有效地完成。)

当您有 {1,2}、{3,4}、{1,2,3,4}、{5,6}、{7,8}、{ 5,6,7,8}。在使用上述过程确定您的操作顺序后,您可以进行优化传递,您可以找到更便宜的方法来评估每个集合的总和(给定已计算的总和),这在实践中可能会给出相当不错的结果。

我怀疑,但没有尝试证明,为给定的一组子集找到最佳过程是 NP-hard 或更糟的。 (它当然是可计算的;您可能进行的计算集是有限的。但是,从表面上看,它可能非常昂贵;您可能会跟踪大约 2^n 部分总和,在每一步将它们中的任何一个添加到任何其他的,并且最多有 n^2 个步骤,对于 (2^2n)^(n^2) = 2^(2n^3) 的超朴素成本) 操作来尝试每一种可能性。)

【讨论】:

    【解决方案2】:

    假设“加法”不仅仅是一个ADD 操作,而是一些涉及两个整数操作数的非常密集的函数,那么一个明显的方法是缓存结果。

    您可以通过合适的数据结构来实现这一点,例如包含由两个操作数组成的键和作为值的答案的键值字典。

    但正如您在问题中指定C,那么最简单的方法是n by n 整数数组,其中x + y 的解决方案存储在array[x][y]

    然后您可以反复迭代子集,并为每对操作数检查数组中的适当位置。如果不存在任何值,则必须对其进行计算并将其放入数组中。然后该值替换子集中的两个操作数并进行迭代。

    如果操作是可交换的,则操作数应在查找数组之前进行排序(即第一个索引始终是两个操作数中最小的),因为这将最大化“缓存”命中。

    【讨论】:

    • 数组需要大于n^2,因为求和的结果也将存储在那里,不是吗?
    • 是的。如果我们想要进行多次传递,并且函数可以返回大于n 的结果,那么array 需要足够大以涵盖所有可能的结果。这就是为什么字典/哈希表可能是更好的数据结构的原因。
    【解决方案3】:

    一种常见的优化技术是预先计算中间结果。在您的情况下,您可以使用来自A 的 2 个加法预先计算所有总和,并将它们存储在查找表中。这将产生|A|*|A+1|/2 表条目,其中|A|A 的基数。

    为了计算 Ai 的元素和,你:

    • 查找Ai的前两个元素之和并保存在tmp中
    • 当 Ai 中还有一个元素 x 时:
    • 查找 tmp 和 x 之和

    为了从您的示例中计算 A1 = {1,3,4,5} 的元素总和,请执行以下操作:

    • 查找(1,3) = 4
    • 查找(4,4) = 8
    • 查找(8,5) = 13

    请注意,计算任何给定 Ai 的总和不需要求和,因为在预先计算查找表时已经进行了所有工作。

    如果将查找表存储在哈希表中,则lookup() 的复杂度为 O(1)。


    这种方法的可能优化:

    • 在计算求和结果的同时构造查找表;因此,您只计算您实际需要的那些总和。您的查找表现在是一个缓存。
    • 如果您的加法运算是可交换的,您可以通过仅存储较小和值先出现的那些总和来节省一半的缓存大小。然后修改lookup() 使得lookup(a,b) = lookup(b,a) if a > b

    【讨论】:

    • 只有当您的查找比您的操作快时,预计算结果才有帮助。在这种情况下,这是不正确的 - 添加比您的查找更快。
    • OP 在他的 cmets 中声明“加法”操作在这台理论机器上非常昂贵/缓慢。
    • ... 假设哈希函数计算不加法。
    • @moooeeeep:我的猜测是 OP 实际上并不是在谈论整数的加法,而是在谈论矩阵或类似的更复杂的加法。
    【解决方案4】:

    如果假设求和是耗时的操作,您可以找到每对子集的LCS(假设它们按照 cmets 中提到的方式排序,或者如果它们没有排序,则对它们进行排序),然后计算最大 LCS 的总和长度(在所有 LCS 上成对),然后用相关数字替换相关数组中的值,更新它们的 LCS 并继续这种方式,直到没有超过一个数字的 LCS。当然这不是最佳的,但它比简单的算法更好(求和的数量较少)。但是,您可以进行回溯以找到最佳解决方案。

    例如对于您的示例输入:

    A1={1,3,4,5} , A2={2,3,4}
    
    LCS (A_1,A_2) = {3,4} ==>7 ==>replace it:
    
    A1={1,5,7}, A2={2,7} ==> LCS = {7}, maximum LCS length is `1`, so calculate sums.
    

    你仍然可以通过计算两个随机数的和来改进它,然后再次取 LCS,...

    【讨论】:

      【解决方案5】:

      没有。没有有效的技术。

      因为是NP complete的问题。并且没有针对此类问题的有效解决方案

      为什么它是 NP 完全的?
      我们可以使用该问题的算法来解决set cover problem,只需将额外的集合放入集合中,包含所有元素。

      示例: 我们有一组元素
      A1={1,2},A2={2,3},A3 = {3,4} 我们要解决集合覆盖问题。

      我们添加到这个集合中,包含所有元素的数字集合 A4 = {1,2,3,4}

      我们使用 John Smith 所寻求的算法,并检查解决方案 A4 是否代表白衣。 我们解决了 NP-Complete 问题。

      【讨论】:

      • 我不确定我是否看到了套装封面问题的链接。如果仅表明我们无法轻松找到最有效的解决方案。我们仍然可以改进幼稚的方法。
      • @GrahamS 有设置封面问题的直接链接。您只需将一个包含所有元素的集合添加到这个求和问题中。解,计算这个最大的集合,就是集合覆盖问题的解,证明这个问题确实很难正确解决。
      猜你喜欢
      • 2015-12-09
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多