我知道Big O和BigΘ的区别,但我发现很少有我需要使用Big O或BigΩ而不是BigΘ的情况。
当给出算法以及运行时间复杂度(平均值,最差值和最佳值)的情况时,我们可以测量算法的运行时间并将其表示为Θ。 (请注意算法意味着问题的清晰和循序渐进的解决方案,如果我错了,请纠正我)
一方面,只说一个算法的运行时间而不指定案例复杂性是不明确的。另一方面,如果它涉及其中一种情况,那么Big O和BigΩ就会失去它们的应用,因为我们特定于案例,最多或至少在那里失去意义。如果我们想要粗糙,我们可以简单地计算T(n)或使用Θ。
例如,快速排序算法的平均时间为Θ(n lg n),最差情况下为Θ(n ^ 2)(因为我们可以计算时间T(n)) )。然而,一些人可以用O(n log n)和O(n ^ 2)来指定它们,但是Θ也是正确且更精确的。
那么我们应该如何或为什么要使用O或Ω来计算这个算法的运行时间? 请不要忘记包含此特定实例的答案。
我不寻求对它们的解释,只是一些我们真正需要大O而不是大Θ的真实例子。
答案 0 :(得分:5)
部分小答案
知道时使用Θ
因为它同时传达了有关O和Ω的消息。你仍然像我在评论中那样加倍你不正确的机会。如果不知道,请使用Ω
答案很长
没关系。测量的是,big O notation
,案例分析是同一问题空间中的正交维度。
O
O
和下限Ω
O
和Ω
,结果相同,从而提供更严格的约束Θ
。 现在,在最坏的情况下提供运行时间的上限是最常用的分析类型。
<强> 注意:的强>
如果给你做作业,它应该说明像
该算法在O方面的最坏情况时间复杂度是多少。
如果您正在解决现实问题,可以从问题本身推断出这些问题。如果您的程序因使用太多内存而被终止,那么进行运行时复杂性分析就没有意义。
要笔直,哪种符号(O,Θ或Ω)以及我们应该使用哪种时间 用于快速排序算法的时间,为什么?
(O, Θ or Ω)
背后的理由是什么?
假设我们有一个像矩阵乘法这样的有趣问题。 人们发现乘法矩阵将有助于几个应用程序,因此他们开始寻找算法。
O(n^3)
的算法。这不是那么低效,所以他继续前进。 O(n^2.807)
Ω
。越高越好。一个界限是Ω(n^2)
。 Ω(n^2 log(n))
的特定范围。它们不是通过提供算法来证明的,而是可以从问题陈述中推断出来。 O(n^2 log(n))
的复杂度来进行矩阵计算,你知道你已经中了大奖。当您获得累积奖金时,您开始使用Θ
一次传达两条消息。O(n^2.237)
最坏情况下不同下限的示例 - 数组中的重新分配
假设您使用数组实现了一个集合。要插入元素,只需将其放入下一个可用存储桶即可。如果没有可用的存储桶,则会将数组的容量增加值m
。
对于插入算法 “没有足够的空间” 是更糟糕的情况。
insert (S, e)
if size(S) >= capacity(S)
reserve(S, size(S) + m)
put(S,e)
假设我们永远不会删除元素。通过跟踪最后一个可用位置,put
,size
和capacity
在空间和记忆中都是Θ(1)
。
reserve
怎么样?如果它像realloc in C那样实现,在最好的情况下,你只需在现有内存的末尾分配新的内存(保留的最佳情况),或者你也必须移动所有现有元素(更糟糕的情况下保留)
insert
的下限是最好的情况
reserve()
,如果我们不挑剔则在m
中是线性的。 insert
in
最坏的情况是空间和时间Ω(m)
。insert
的最坏情况上限是更糟糕的情况
reserve()
,在m+n
中是线性的。在最坏的情况下,insert
是
空间和时间O(m+n)
。答案 1 :(得分:2)
大O和最佳/平均/最差看看执行速度的不同方面。
Big O /BigΘ没有说明一些代码需要多长时间才能运行 它说运行时间取决于输入大小。
实际时间取决于多种因素,几乎所有因素都被忽略。 (见下文脚注)
最佳/最差/平均/典型是完全不同的运行时间。 它们(通常)比Big O表示法更具体 - 但通常时间以Big(O)给出:
哈希表查找的典型时间是O(1)。最坏的情况是O(N)
请注意,此声明在技术上是不正确的:Big O 不指定时间。该陈述的迂腐版本将是:
在典型情况下,查找一个元素的时间或多或少与哈希表中的项目数(O(1))无关。最坏的情况是,查找时间与表中的项目数(O(N))成比例增长。
脚注:
大O符号甚至忽略了增长最快的术语。
如果您有两个具有确定性运行时间的算法
tA(N) = 10s * N^2 + 1s * N + 42 days
tB(N) = 1 day * N^2
两者都是O(N^2)
即使第二个对于大N来说显然更糟,但这并没有在Big O中表达。
请记住,虽然运行时是Big O表示法的最常用用途,但它也可用于内存使用或磁盘访问或交换等特定操作。
关于您的更新:
算法的运行时间是指什么,当没有指定案例时?在最坏的情况下,它是指算法的运行时间吗?平均情况或最佳情况?
正式:如果没有指定,则没有指定。
非正式地说,在给定的背景下最有意义的东西。如果没有指定任何内容,大多数人会认为它是平均的或至少是典型的情况 - 但是你依赖的程度取决于你。
分区排序:
形式上,没有具体说明,
- 任何O(f(N)) >= O(N^2)
在没有指明案例的情况下都是正式的。即使O(N^N)
也是正确的,只是没用。
- 任何Ω(f(N)) <= O(n lg n)
规范
需要指定的内容取决于上下文。
API通常会尽可能少地指定,以便为实现留出灵活性。例如。它可能指定“检索处于摊还的常数时间”,这意味着O(1)典型情况下最坏情况更糟糕但很少发生。
API通常也只会指定Big O,,除非有更快更糟的特殊原因(例如旁道攻击)。
另一方面,完整的规范会充分指定算法,您可以自己计算所有情况的O和Ω - 以及 more 。如前所述,Big O /Ω可能不足以做出有关运行时行为的明智决策。
Inbetween,无论需要什么:
通常,O比其他更常见,因为Ω几乎从不相关,并且Θ并不总是可用。
如果只指定了一个值,则通常是平均值或典型时间,因为这样可以判断算法的“值”。
如果指定了两个值,则最坏情况另外,因为后者是比较具有相同典型行为的算法时最常见的标准,或者您有实时要求。
接下来会出现性能下降的条件。因为“O(N)典型的算法,百万分之一输入中的O(N ^ 2)”与“O(N)典型,O(N)完全不同^ 2)在星期一早晨“。
如果仍然不足,您通常会看到特定操作的最大数量,例如“最多N ^ 2 + 1个comarisons和N / 2-1交换”。
答案 2 :(得分:-2)
因此,除非另有说明,否则θ和O通常都指算法的平均运行时间。因此,分区排序是O(nlogn)和theta(nlogn)。
它们不同的原因在于,有时可以很容易地看到/证明平均情况并不比某些功能差,但仍然难以证明它的运行情况时间平均,或在某些情况下,证明什么是最佳运行时间。
例如,当multiplying matrices明确表示您可以使用O(n ^ 3)算法时,因为这就是您手动完成的方法。最着名的算法是theta(n ^ 2.4),粗略地说。然而,其他一些数学家声称算法的下限是Omega(n ^ 2 log n),而其他研究人员声称这是错误的,并且存在theta(n ^ 2)算法。