【问题标题】:Comparing Complexity Of Algorithms比较算法的复杂性
【发布时间】:2019-06-12 21:50:24
【问题描述】:

我目前正在学习 Big O Notation 的运行时间和摊销时间。

我有以下问题:

两种基于分治原则的算法可用于解决复杂度为 n 的问题。 算法 1 将问题分为 18 个小问题,需要 O (n^2) 次操作将子解决方案组合在一起。 算法 2 将问题分为 64 个小问题,需要 O(n) 次操作将子解组合在一起。

哪种算法更好更快(对于较大的 n)?

我猜测第二种算法更好,因为它需要更少的时间(O(n) 比 O(n^2) 快)。 我猜对了吗?

小问题的数量对算法的速度有影响还是总是需要一个恒定的时间?

【问题讨论】:

  • a priori,是的。由于 n --> 无穷大,第二个更好。但在某些情况下,即使对于相当大的“n”,第一个更好。这取决于所涉及的常量。
  • 假设算法 2 优于 n -> 无穷大是不正确的。为了准确确定哪种算法更快,您缺少我和哈罗德在下面讨论的信息。

标签: algorithm data-structures time-complexity big-o notation


【解决方案1】:

在这种情况下,它可能不打算成为一个陷阱,但最好小心一点,并且可能会发生一些违反直觉的事情。如果发生这种情况,陷阱主要是这样的:与生成的子问题相比,子问题的大小要​​小多少?

例如,这里的算法 1 是正确的,如果子问题的大小是当前问题大小的 1/5 或更小(也许它们意味着它们将是大小的 1/18?),那么总体而言时间复杂度为 O(n²)。但是如果问题的大小只下降了 4 倍,我们已经达到了 O(n2.085),并且如果域只被分成了一半(但仍然是 18 倍)然后一直到 O(n4.17)。

与算法 2 类似,如果它把一个程序分成 64 个子问题,每个子问题的大小是 1/64,那么总的时间复杂度将在 O(n log n) 中。但是如果子问题稍微大一点,比如大小的 1/63,我们会立即在层次结构中上升一个完整的步骤到 O(n1.004) - 指数中的一个小常数仍然,但不再是对数线性的。使问题的大小变成原来的 1/8,复杂度变成二次方,如果我们在每一步中仅将问题大小减半,那么它一直到 O(n6)!另一方面,如果问题只缩小了一点,比如大小的 1/65,那么复杂性立即不再是对数线性的,但这次是在另一个方向上,变为 O(n)。

所以它可以是任何一种方式,具体取决于子问题缩小的速度,这在您的问题陈述中没有明确提及。希望很明显,仅比较“每一步的附加处理”是不够的,无论如何都不是。每步处理量大是无法克服的缺点,但如果“收缩因子”与“扇出因子”相比,“收缩因子”较小,则每步只进行少量处理是很容易失去的优势。

【讨论】:

    【解决方案2】:

    Master theorem 用于分治算法的渐近分析,它将为您提供一种获得直接答案而不是猜测的方法。

    T(n) = aT(n/b) + f(n)   
    

    其中 T 是主要问题,n 是输入集,a 是您划分的子问题的数量,b 是您的输入集针对每个子问题减少的因子,f(n) 是函数将子问题拆分和组合在一起。从这里我们找到 c:

    f(n) is O(n^c)
    

    例如,在您的示例算法 1 中,c = 2,在算法 2 中,c = 1。算法 1 和 2 的值 a 分别为 18 和 64。下一部分是您的问题缺少适当信息的地方,因为未提供 b。 换句话说,要得到一个明确的答案,你需要知道每个子问题划分原始输入的因子。

    if c < logb(a) then T(n) is O(n^logb(a))
    if c = logb(a) then T(n) is O(n^c log(n))
    if c > logb(a) then T(n) is O(f(n))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2020-11-25
      相关资源
      最近更新 更多