【问题标题】:How to add/merge several Big O's into one如何将几个大 O 添加/合并为一个
【发布时间】:2009-11-14 11:51:45
【问题描述】:

如果我有一个由(比方说)三个子算法组成的算法,它们都具有不同的 O() 特征,例如:

  • 算法 A:O(n)
  • 算法 B:O(log(n))
  • 算法 C:O(n log(n))

我如何从理论上估计整个算法的 O()? IE。不计时或执行任何其他实际测量。

是否有众所周知的公式或程序?

【问题讨论】:

  • 将表现最差的部分作为整体表现是否有意义?
  • 只是一个警告,以确保每个算法中的“n”指的是相同的东西,否则你会陷入困境。

标签: algorithm big-o estimation


【解决方案1】:

是否有众所周知的公式或程序?

因为这是基础数学,是的。但在你的情况下更简单:因为所有这些都给出了一个上限,你可以简单地取所有边界中的最大值来获得总上限。

– 前提是所有这些算法都是链式(而不是嵌套式)。如果算法是嵌套的,则需要乘以它们的上限(在最简单的情况下)。

为了说明,假设您有一个容器数据结构,其查找单个元素的成本为 O(log n)。您还有一个算法需要这样的查找,但它本身的运行时间为 O(n),假设 查找的成本恒定,并在输入上使用单个循环,每个循环的查找次数恒定。

现在,如果你想在这个算法中使用前面提到的容器数据结构,它的查找运行时显然取代了(假设的)恒定时间查找。所以我们有相同的循环,但是它的每次迭代现在都需要 O(log n) 而不是恒定时间 O(1),所以整体运行时间变成 O(n 记录 n)。

【讨论】:

  • 如何将例如 O(n) 与 O(n log(n)) 相乘?
  • @R.A.:通过乘以指定边界的函数,即结果将是 O(n^2 log n)。
【解决方案2】:

“总”复杂度是所有​​子算法中最坏的情况。在您的示例中:O(n*log(n))

Definition of O(f(n)) 是从某个数字(某个 n0)开始,有一个常数“Const”,其中对大小为 n 的输入的操作总数小于 Const*f(n)

因此,如果您有一组子算法,复杂度将始终小于所有 const 的 Sigma (Const1 + Const2 + ...) 乘以最差复杂度函数(例如,从 "n"、"n* logn" 和 "n^2" 将是 n^2)。根据复杂性定义,它是该组中最差的复杂性。

例子:

  1. 假设我们正在对数组进行排序(n*logn)
  2. 找到键高于x的项目(logn)

假设排序的 Const1 是 5(意味着我们可以在少于 5*n*logn 的动作中对 n 个项目的列表进行排序),而 Const2 是 3(意味着我们可以在少于 3*logn 的动作中找到元素)。

在这种情况下,很明显两种算法的动作总数都小于(5+3)*n*logn动作,因此它是O(n*logn)

【讨论】:

  • 这取决于算法是否相对于彼此运行相同的次数,或者是否存在乘法效应,在这种情况下,您必须将它们相乘。
  • @Joe,你说得对,这个分析与序列运行有关,而不是与嵌套运行有关,我希望这是个问题 :) 如果某些算法运行不止一次,结果保持不变只要次数是常数并且不依赖于n。
【解决方案3】:

O(n) 算法效率估计的假设之一是我们的实际运行时间接近理论值。因此,我们不应该过于纠结于轴试图找出小的差异。例如,如果我们对未排序的数据集进行简单的迭代搜索(平均而言,我们会在中间点找到值),那么 O(n) 算法可能会在 O(n/2) 时间内完成,但它仍然是一个 O(n) 算法。

如果你有一个函数必须在一个数据集上完成三个子进程才能退出,那么可以说,该数据集上运行时间最慢的子进程将是帐篷中最长的杆子。在给出的具体示例中,函数 ('algorithm') 运行时间为 O(n),如果是 O(n + n*log(n) + log(n)),我们不必担心;该总和与 O(n) 之间的差异最多是两倍。我们关心的是相对量级,即运行时间是 log(n) 还是 (n) 或 (n^2) 或 (n^3) 无穷大。我们关心的是 10 或 100 或 1000 的因数。

【讨论】:

    【解决方案4】:

    问题的复杂性是由“n”趋于无穷大的条件决定的。这个链接从根本上是为什么所有复杂度较低的 O(n) 数都被丢弃的原因;甚至 O(n) 格式也会丢弃其他多项式项,这些项会在不同的硬件上发生变化。合理地,如果您有函数的次数,您可以添加各种总次数。在时间相关的环境中,这可能是有意义的数据,例如处理大量数据,其中多次调用被调用的函数。这也可以提供解决方案的可扩展性和升级的性能峰值,让我们说,服务器。这将是一个单机解决方案,并且系数也不会被丢弃。

    所有机器在执行任何基于架构的功能以及编译器如何生成二进制代码时都会有不同的运行系数。这意味着,如果您正在为多个用户设计程序,并且他们在不同的计算机上,那么具体的计算不仅无关紧要,而且也不准确。

    如果计算不是无关的或不准确的:

    分离结构的诀窍是一个的时间函数不是所有其他的时间函数。

    O(n) = x + y + z, 
    x(n) = (t1) * (n^2)
    y(n) = (t2) * (log n) 
    z(n) = (t3) * (n log n) 
    

    ...

    时间 (t1)、(t2) 和 (t3) 作为函数在特定机器上的时间给出。

    【讨论】:

      猜你喜欢
      • 2022-12-08
      • 2020-07-03
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 2019-01-18
      • 2019-11-24
      • 1970-01-01
      • 2010-10-16
      相关资源
      最近更新 更多