繁体   English   中英

算法最坏情况运行时间的上限与下限

[英]Upper bound vs lower bound for worst case running time of an algorithm

我正在学习算法分析。 我理解算法的最坏情况运行时间的概念。

但是,算法在最坏情况下运行时间的上限和下限是多少?

有什么可以将上结合用于运行算法的时间最坏情况下的例子是从不同的下限为运行相同的算法的时间的最坏情况?

对于函数f(n)g(n)上限大 O ),如果对于“足够大的 n”, f(n)<=c*g(n) ,对于常量c [g 支配 f]
g(n) 是下限大 Omega ),如果对于“足够大的 n”, f(n) >= c*g(n) ,对于常数c [f 支配 g]

如果g(n)f(n)上界和下界 [具有不同的 c],我们说 g(n) 是 f(n) [Big theta] 的紧界

使用上界而不是紧上界的例子:有时,很难找到紧上界,例如斐波递归算法。 所以我们很容易找到 O(2^n) 的简单上界。 在这篇文章的答案中可以找到更多信息。

它与最坏/基本/...情况有什么关系? (根据评论要求):

最坏情况/平均情况(或任何其他情况)会影响复杂度函数是什么,但 big-O、big-Omega 和 big-Theta 可以应用于这些情况中的每一种。

例如,HashTable 插入是Θ(1)平均情况插入和Θ(n)最坏情况插入。 它也是O(n)平均情况插入(边界不严密)和Ω(1)最坏情况插入。

首先,让我们谈谈案例。 算法输入案例问题实例相关联。 对于排序问题(我们希望以特定顺序查找集合的排列),我可以查看一个实例,例如数字集合 {1, 5, 4, 2, 6}。 这组数字将成为旨在解决排序问题的排序算法的输入,例如选择排序或其他排序算法之一。

可以为任何想要解决问题的算法提供相同的输入集。 不管我使用什么排序算法,输入集总是相同的(因为,根据定义,它们都是同一问题的实例)。 但是,对于给定算法,给定情况可能更好或更糟。 无论输入是什么,有些算法总是执行相同的操作,但有些算法在某些输入上可能表现更差。 然而,这意味着每个算法都有一些最好的情况和一些最坏的情况; 我们有时也会谈论平均情况(通过取所有情况的平均值)或预期情况(当我们有理由预期一种情况会比其他情况更常见时)。

算法案例示例

“找到未排序列表的最小值”的问题对于每个可能的输入总是相同的。 不管你写什么聪明的算法,你都必须检查每一个元素。 如果您有一个零列表或随机数列表或第一个元素是最小值的列表,这并不重要,直到您到达最后才知道。 该算法的每种情况都是相同的,因此最好的情况是最坏的情况,平均情况和预期情况也是如此。 如果列表被排序,我们可以做得更好,但这是一个不同的问题。

“在列表中查找给定元素”的问题是不同的。 假设您使用的是对列表进行线性遍历的算法,结果可能是给定元素是列表的第一个元素,并且您会立即完成。 但是,它也可能是列表的最后一个元素,在这种情况下,您必须遍历整个内容才能找到它。 所以你有一个最好的情况和一个最坏的情况。

作为输入大小函数的算法

当我们想要分析一个算法时,我们算法学家会考虑我们可以向算法抛出的每一种可能情况。 通常,两个最有趣的情况是最好的情况和最坏的情况。 如果您将算法运行时视为其输入的函数,那么最好的情况是最小化函数的输入,而最坏的情况是最大化函数的输入。 我在这里使用代数数学意义上的“函数”:绘制一条线的一系列 x/y 对(输入/输出对,或在本例中为“输入大小/执行步骤数”)。

由于算法的运行时间是其输入的函数,因此对于每种可能的输入大小,我们都有不同的最佳情况(和最坏情况)。 所以有时我们将最好的情况视为单个输入,但它实际上是一组输入(每个输入大小一个)。 对于给定的算法来说,最好的情况和最坏的情况是非常具体的事情。

界限

现在边界呢? 边界是我们用来与给定算法的函数进行比较的函数。 我们可以考虑无数的边界函数。 您可以在图形上绘制多少种可能的线条? 这就是边界函数的数量。 大多数算法学家通常只对一些特定的函数感兴趣:常数函数、线性函数、对数函数、指数函数等。

上限是位于另一个函数之上的函数。 下限是位于另一个函数之下的函数。 当我们谈论 Big O 和 Big Omega 时,我们并不关心边界是否总是高于或低于另一个函数,只是在某个点之后它们总是如此(因为有时算法对于小输入大小会变得奇怪)。

任何给定函数都有无数个可能的上限,任何给定函数都有无数个可能的下界。 但当我们谈论不同大小的无穷大时,这是那些奇怪的时期之一。 作为上限,该函数不能低于另一个函数,因此我们排除了另一个函数下面的无限多个函数(因此它小于所有可能函数的集合)。

当然,仅仅因为有无限的上限,并不意味着它们都是有用的。 函数 f(∞) 是每个函数的上限,但这就像在说“我的钱少于无穷多”——对于确定我是身无分文还是百万富翁来说并不是特别有用。 因此,我们经常对“紧”的上限(也称为“最小上限”或“最高”)感兴趣,对此没有更好的上限。

最佳/最差情况 + 下限/上限

我们有代表算法运行时函数的上函数和下函数的最佳/最坏情况。 我们有上界和下界代表其他函数,它们可能位于(分别)任何其他函数的顶部或下方。 它们可以结合起来表达关于算法的关键思想。

最坏情况下界:当算法被赋予最大化算法运行时间的输入时,该函数是算法运行时函数下方的边界。

Worst Case Upper Bound :一个函数,它是算法运行时函数之上的边界,当该算法被赋予最大化算法运行时间的输入时。

最佳情况下界:当该算法被赋予最小化算法运行时间的输入时,该函数是算法运行时函数下方的边界。

最佳情况上限:当该算法被赋予最小化算法运行时间的输入时,该函数是算法运行时函数之上的边界。

大小写边界的例子

让我们举出具体的例子来说明我们什么时候可能会关心这些:

最坏情况下界:这里的经典示例是基于比较的排序,众所周知,在最坏情况下为 Ω(n log(n))。 无论你设计什么算法,我都可以选择一组最坏情况的输入,其中最紧密的下界函数是对数线性的。 您无法制作出能够超越最坏情况的算法,您也不应该费心去尝试。 它是排序的基础。 当然,最坏的情况有很多下界:常数、线性和次线性都是下界。 但它们不是有用的下限,因为对数线性下限是最严格的。

最佳情况下界插入排序的工作原理是遍历列表,并将遇到的任何乱序插入到正确的位置。 如果列表已排序,则只需要遍历列表一次而无需执行任何插入操作。 这意味着最好情况的最严格的下限是 Ω(n)。 你不能在不牺牲正确性的情况下做得更好,因为你仍然需要能够遍历列表(线性时间)。 然而,最好情况的下限比最坏情况的下限要好!

最坏情况上限:我们经常对在最坏情况下找到一个严格的上限感兴趣,因为这样我们就知道我们的算法在最坏的情况下运行得有多糟糕。 插入排序的最坏情况是一个完全无序的列表(即完全颠倒其正确顺序)。 每次我们看到一个新项目时,我们必须将它移动到列表的开头,将所有后续项目向前推(这是一个线性时间操作,执行线性次数会导致二次行为)。 然而,我们仍然知道这种插入行为在最坏情况下将是 O(n2),作为最坏情况下的严格上限。 这不是很好,但它比指数或阶乘的上限要好! 当然,这些是最坏情况下的有效上限,但这又不如知道二次方是一个紧上限那么有用。

最佳情况上限:我们的算法在最好的情况下能做到的最坏情况是什么? 在之前在列表中查找元素的示例中,第一个元素是我们想要的元素,上限是 O(1)。 在最坏的情况下它是线性的,但在最好的情况下,可能发生的最坏情况是它仍然是恒定的。 在我看来,这个特定的想法通常不如 Worst Case Upper Bound 重要,因为我们通常更关心处理最坏的情况,而不是最好的情况。

其中一些示例实际上是 Ө,而不仅仅是 O 和 Ω。 在其他情况下,我可以选择不紧的下​​界或上界函数,但仍然足够近似以供使用(请记住,如果我们不紧,我有无限的井可以从中汲取!)。 请注意,可能很难找到不同 case/bound 组合的引人注目的示例,因为这些组合具有不同的效用。

误解和术语

通常,您会看到人们对这些定义有误解 事实上,许多非常优秀的计算机科学家会松散地互换使用这些术语。 然而,case 和 bounds 的概念是不同的,你最好确保你理解它们。 这是否意味着差异会出现在您的日常生活中? 不。但是当您在几种不同的算法之间进行选择时,您需要阅读有关案例和界限的细则。 有人告诉你他们的算法有一个 O(1) 的最佳情况上界可能是想把羊毛拉到你的眼睛上 - 确保你问他们最坏情况上界是什么!

让我通过一个例子来说明这一点:

快速排序的最坏情况运行时间是Theta(n^2) 所以一个有效的下限是Omega(n) ,上限是O(n^3) 这表示在最坏的情况下,快速排序将花费至少线性时间和最多三次时间。

现在这不是一个非常精确的陈述,但对于更复杂的算法,这样的陈述是我们能做的最好的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM