如何将几个Big O添加/合并为一个

时间:2009-11-14 11:51:45

标签: algorithm big-o estimation

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

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

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

是否有众所周知的配方或程序?

4 个答案:

答案 0 :(得分:9)

  

是否有众所周知的配方或程序?

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

- 假设所有这些算法都是链接(而不是嵌套)。如果算法是嵌套的,则需要将它们的上限相乘(在最简单的情况下)。

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

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

答案 1 :(得分:4)

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

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

因此,如果你有一组子算法,复杂性将始终小于所有consts的Sigma(Const1 + Const2 + ...)乘以最差复杂度函数(例如,来自“n”,“n *登录“和”n ^ 2“它将是n ^ 2)。根据复杂性定义,它是该组中最差的复杂性。

示例:

  1. 我们假设我们正在对数组(n*logn)
  2. 进行排序
  3. 使用更高的键找到项目,然后 x (logn)
  4. 假设排序的Const1是5(意味着我们可以在少于5 * n * logn动作中对n个项目的列表进行排序)并且Const2是3(意味着我们可以在少于3 *个logn动作中找到该元素)。

    在这种情况下,很明显两种算法的操作总数少于(5+3)*n*logn次操作,因此O(n*logn)

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

问题的复杂性取决于“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)作为特定机器上的功能的时间给出。