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

时间:2011-10-02 20:25:52

标签: algorithm complexity-theory

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

然而,算法的最坏情况运行时间的上限和下限是什么?

对于算法的最坏情况运行时间的上限下限的最差情况运行时间不同,可以是什么示例算法

3 个答案:

答案 0 :(得分:9)

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

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

使用示例作为上限而不是紧的:有时很难找到紧束缚,例如fibonacci递归算法。所以我们很容易找到O(2 ^ n)的容易上界。更多信息可在此post的答案中找到。

答案 1 :(得分:1)

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

quicksort的最坏情况运行时间是Theta(n^2)。因此,有效下限为Omega(n),上限为O(n^3)。这表示在最糟糕的情况下,quicksort将采用至少线性时间和最多立方时间。

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

答案 2 :(得分:1)

首先,让我们谈谈案例。 算法输入案例问题实例相关。对于排序问题(我们要按特定顺序查找集合的排列),我可以看一个像数字{1、5、4、2、6}的集合这样的实例。这组数字将作为排序算法的输入,该算法旨在解决排序问题,例如选择排序或其中的other sorting algorithms

可以为要解决问题的任何算法提供相同的输入集。我使用哪种排序算法都没有关系,输入的集合始终是相同的(因为按照定义,它们都是同一问题的实例)。但是,对于给定算法,给定情况可能更好或更糟。不管输入是什么,某些算法总是执行相同的操作,但是某些算法在某些输入上的性能可能会更差。但是,这意味着每种算法都有最好的情况和最坏的情况;我们有时还会谈论“平均情况”(取所有情况的平均值)或“预期情况”(当我们有理由期望一个情况比其他情况更普遍时)。

算法案例示例

对于所有可能的输入,“查找未排序列表的最小值”的问题始终是相同的。无论您编写哪种聪明的算法,都必须检查每个元素。拥有零列表,随机数列表或第一个元素为最小值的列表都没关系,直到结束时才知道。该算法的每种情况都是相同的,因此最好的情况是最坏的情况,还有平均情况和预期情况。如果对列表进行排序,我们可以做得更好,但这是另一个问题。

“在列表中查找给定元素”的问题不同。假设您使用的是对列表进行线性遍历的算法,则可能会发现给定元素是列表的第一个元素,您将立即完成操作。但是,它也可能是列表的最后一个元素,在这种情况下,您必须先走遍整个事物,然后才能找到它。因此,这里有一个最好的情况,一个最坏的情况。

算法作为输入大小的函数

当我们要分析算法时,我们的算法专家会考虑我们可能对算法提出的所有可能情况。通常,两个最有趣的情况是最好的情况和最坏的情况。如果您将算法运行时视为其输入的函数,则最好的情况是使函数最小化的输入,而最坏的情况是使函数最大化的输入。我在这里使用的是代数数学意义上的“函数”:一系列x / y对(输入/输出对,在这种情况下为“输入大小/执行步骤数”),它们画一条线。

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

界限

现在边界如何?界限是我们用来与给定算法的功能进行比较的功能。我们可以考虑无限多个边界函数。您可以在图形上绘制多少种线条?那就是有多少个边界函数。大多数算法专家通常只对一些特定功能感兴趣:诸如常数函数,线性函数,对数函数,指数函数等。

上限是一个位于另一个函数之上的函数。下限是位于其他功能之下的功能。当我们谈论Big O和Big Omega时,我们并不在乎边界总是在另一个函数之上还是之下,只是在某个点之后它们始终是(因为有时算法对于小输入量来说很奇怪)。

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

当然,仅因为存在无限的上限,并不意味着它们都有用。函数f(∞)是每个函数的上限,但这就像说“我拥有的美元数量不限”一样-对于弄清我身无分文还是百万富翁而言,它并不是特别有用。因此,我们通常对“紧”的上限(也称为“最小上限”或“最高”)感兴趣,而没有更好的上限。

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

我们有最好/最坏的情况,它们代表算法运行时函数的上,下函数。我们具有代表其他功能的上限和下限,这些上限可以分别位于任何其他函数的上方或下方。可以将它们结合起来以阐明有关算法的关键思想。

最坏情况下界:该函数是算法运行时函数下方的边界,当为该算法提供了可以最大化算法运行时间的输入时。

最坏情况上界:该函数是算法运行时函数上方的边界,当为该算法提供了使算法运行时间最大化的输入时。

最佳情况下界:该函数是算法运行时函数下方的边界,当为该算法提供了使算法运行时间最小化的输入时。

最佳情况上限:该函数是算法运行时函数上方的边界,当为该算法提供了使算法运行时间最小化的输入时。

案例界限示例

让我们举一些具体的例子说明何时我们可能会关心这些东西:

最坏情况下界:此处的经典示例是基于比较的排序,众所周知,最坏情况下为Ω(n log(n))。无论您采用哪种算法,我都可以选择一组最坏情况的输入,其中最严格的下界函数是对数线性的。在最坏的情况下,您无法制定出超越极限的算法,也不必费心尝试。这是排序的基础。当然,在最坏的情况下,有许多下界:常数,线性和次线性都是下界。但是它们不是有用的下限,因为对数线性下限是最严格的下限。

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

最坏情况的上限:我们通常对找到最坏情况的严格上限感兴趣,因为这样我们就知道我们的算法在最坏情况下的运行情况有多么差。插入排序最坏的情况是一个列表完全乱序(即,与正确顺序完全相反)。每次看到新项目时,我们都必须将其移至列表的开头,将所有后续项目向前移动(这是线性时间操作,并且对其进行线性次数将导致二次行为)。但是,我们仍然知道,在最坏的情况下,此插入行为将为O(n2),充当最坏情况的严格上限。这不是很好,但是比指数或阶乘的上限好!当然,在最坏的情况下,这些值是有效的上限,但这又不如知道平方是一个严格的上限有用。

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

其中一些示例实际上是Ө,而不仅仅是O和Ω。在其他情况下,我可能选择了不严格的下限或上限函数,但仍然足够近似有用(请记住,如果我们不严格,则可以从中无限取用!)。请注意,由于案例/绑定组合的效用不同,因此很难找到令人信服的示例。

误解和术语

通常,您会看到people with misconceptions关于这些定义的信息。实际上,许多非常优秀的计算机科学家都会松散地互换使用这些术语。但是,案例与界限的概念是截然不同的,因此您最好确保了解它们。这是否意味着每天都会有所不同?不会。但是,当您在几种不同的算法之间进行选择时,您希望阅读有关情况和范围的详细信息。有人告诉您他们的算法的最佳情况上界为O(1),可能是在试图将羊毛拉到您的眼睛上-确保您询问他们最糟糕的情况上界是什么!