渐近符号

621 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

渐近符号

我们使用一种称为渐近符号的东西来提供一种正式的方式来讨论算法的运行时间与其输入大小之间的关系。其基本动机是,当在小输入上运行时,几乎任何算法都足够有效。我们通常需要担心的是算法在非常大的输入上运行时的效率。作为“非常大”的代理,渐近符号描述了算法的复杂性,因为其输入的大小接近无穷大。

image.png

如果我们假设每行代码需要一个单位的时间来执行,则此函数的运行时间可以描述为1000 + x + 2x2。常量 1000 对应于执行第一个循环的次数。术语 x 对应于执行第二个循环的次数。最后,术语 2x2 对应于在嵌套的 for 循环中执行这两个语句所花费的时间。因此,调用 f(10) 将打印

image.png

并且调用 f(1000) 将打印

image.png

对于 x 的较小值,常量项占主导地位。如果 x 为 10,则第一个循环会占用超过 80% 的步长。另一方面,如果 x 为 1000,则前两个循环中的每一个仅占步骤的 0.05% 左右。当 x 为 1,000,000 时,第一个循环大约需要总时间的 0.00000005%,第二个循环大约需要 o.00005%。2,000,000,000,000,000 个步骤中的 2,000,001,000 个步骤位于内部 for 循环的主体中。

显然,通过仅考虑内部循环(即二次分量),我们可以获得一个有意义的概念,即此代码在非常大的输入上运行需要多长时间。我们是否应该关心这个循环需要2x2步而不是x2步的事实?如果您的计算机每秒执行大约 1 亿个步骤,则计算 f 大约需要 5.5 小时。如果我们能将复杂性降低到x2步,大约需要2.25小时。无论哪种情况,寓意都是一样的:我们可能应该寻找一种更有效的算法。

这种分析导致我们使用以下经验法则来描述算法的渐近复杂性:

·如果运行时间是多个项的总和,请保留增长率最高的项,并删除其他项。

·如果剩余项是乘积,请删除所有常量。

最常用的渐近符号称为“Big O”符号.67 Big O符号用于给出函数的渐近增长(通常称为增长顺序)的上限。例如,公式 f(x) e o(x2) 意味着函数 f 的增长速度不快于二次多项式 x2,在渐近意义上。

许多计算机科学家会滥用Big O符号,做出这样的陈述,“f(x)的复杂性是o(x2)”。他们的意思是,在最坏的情况下,f将不超过o(x2)步骤来运行。函数“在 o (x)中”和“在 o (x2)中”之间的区别是微妙的,但很重要。说 f(x) E 0(x2) 并不排除 f 的最坏运行时间大大小于 o(x2)。为了避免这种混淆,当我们描述的东西既是渐近最坏情况运行时间的上限又是下限时,我们将使用Big Theta(θ)。这称为紧密绑定。

image.png

练习:以下每个函数的渐近复杂性是什么?

image.png