对数复杂度的算法直觉


59

我相信我对,和这样的复杂性有一定的了解。Θ n Θ n 2O(1)Θ(n)Θ(n2)

就列表而言,是一个常量查找,因此它只是成为列表的开头。 是我遍历整个列表的位置,而对于列表中的每个元素遍历该列表一次。Θ n Θ n 2O(1)Θ(n)Θ(n2)

除了只知道位于和之间,有没有类似的直观方法来掌握它?Θ(logn)Θ n O(1)Θ(n)


8
log n用于“搜索”:认为二进制搜索
Suresh 2012年

2
使用O来问这个问题是不正确的,因为它仅表示一个上限。例如,恒定时间为O(logn)θ会更合适。参见meta问题:meta.cs.stackexchange.com/questions/182/…–
Aryabhata


注意事项:在传统的Turing Machine设置中,所有算法均为,因为它们需要至少一次读取输入的每个符号。二进制搜索可以在O log n )中完成,因为例如,我们可以保证列表已排序。Ω(n)O(logn)
chazisop 2012年

1
后来的贡献:从定义上来说,数字n的底对数就是将b自身乘以n的次数b l = nbnbn。例如 2 3 = 8bl=nl=logb(n)。因此,如果您有一个数字 n,并且想找出 l o g bn = 只需将其除以 b直到达到 1(为简单起见,假设 n b的幂)即可。除法数等于 l o g bn 。表现出这种除法行为的算法的运行时间为 O l o g23=8log2(8)=3nlogb(n)=?b1nblogb(n)O(log(n))
saadtaame 2012年

Answers:


53

复杂性通常与细分连接。以列表为例时,请想象一个列表,其元素已排序。您可以在Olog n 时间内在此列表中搜索-由于列表的排序性质,实际上您不需要查看每个元素。Θ(logn)O(logn)

如果查看列表中间的元素并将其与搜索的元素进行比较,则可以立即说出它是位于数组的左半边还是右半边。然后,您可以只取一半,然后重复该过程,直到找到它或找到一个列表,其中包含一项要比较的项目。

您可以看到列表有效地将每一步减半。这意味着,如果获得长度为的列表,则到达一个项目列表的最大步骤为5。如果您有128 = 2 7个项目的列表,则只需要7步;对于1024 = 2 10的列表,则只需10个步,依此类推325128=2771024=21010

正如你可以看到,指数2 ñ始终显示的必要步骤。对数用于精确地“提取”该指数,例如log 2 2 10 = 10。它还可以概括列出不是2​​的幂的长度。n2nlog2210=10


4
应该注意的是,这仅O(log n)在列表具有恒定时间随机访问的情况下。在更典型的列表实现(链接列表)上,这是O(n log n)
asm

1
由于缺少指针,二进制搜索不适用于列表。它通常在数组上完成。
拉斐尔

二进制搜索在列表上很好用。由于比要求/充分/实用要复杂得多,因此这毫无意义。
安东

@AndrewMyers搜索链接列表更准确O(n)
phant0m 2012年

1
@ phant0m是的,我花了一点时间才弄清楚,这是假设您是从当前位置开始移动,而不是每次都从头开始移动。
asm 2012年

38

就(平衡)树而言(例如,二叉树,因此所有均以2为底):log

  • 正在获取树的根Θ(1)
  • 是从根到叶的步行Θ(logn)
  • 正在遍历树的所有节点Θ(n)
  • 是对树中两个节点的所有子集的操作,例如,任意两个节点之间的不同路径的数量。Θ(n2)
  • -上面对于 k个节点的任何子集的推广(对于常数 kΘ(nk)kk
  • 是在节点上的所有可能的子集的操作(所有可能的大小的子集,即, ķ = 1 2 ... Ñ)。例如,的不同子树的数量。Θ(2n)k=1,2,,n

5
除此之外,来自两件事:1.)递归 T n = T Θ(loglogn)和2。)对大小为logn)的东西进行二进制搜索,即对树的高度进行二进制搜索。T(n)=T((n))+1log(n)
mcorley 2012年

17

为了使成为可能,您需要能够通过恒定时间操作相对于n按比例任意减小问题大小。O(logn)n

例如,对于二进制搜索,您可以通过每次比较操作将问题大小减少一半。

现在,您是否必须将问题大小减少一半,实际上没有。即使可以将问题搜索空间减少0.0001%,该算法也是,只要它用于减少问题大小的百分比和用于运算的常量保持不变,它就是O log n 算法,它不会是一个快速的算法,但是它仍然是O log n ,具有很大的常数。(假设我们正在讨论以2为底的log nO(logn)O(logn)O(logn)logn


1
如果“下切量”不恒定会怎样?
Svish 2012年

@Svish如果您可以以一个积极的速度解决问题,尽管它可能不再是一个严格的界限,但它仍将是算法。负面率很难说。在这种情况下,做出此假设的目的是使答案相当简单,因为该问题有其自身的优点,因此非常欢迎您单独提出这个问题。O(logn)
肯李

是的,我的意思是问题搜索空间总是在减少,但不一定保持恒定的速度。只是想着您“只要减少问题大小的百分比和所使用的操作保持不变,这就是O(log n)算法”;如果名称不相同,则百分比不同。
Svish 2012年

8

考虑将十进制数转换为二进制的算法n

while n != 0:
   print n%2, 
   n = n/2

while循环运行次。log(n)


1
当然,该程序会循环次,但是通常当我们谈论O f s 复杂度时,s是您输入的大小。这里您输入的大小已经是s = log n,所以我想说这个程序只是线性的(以O s lognO(f(s))ss=lognO(s)
jmad 2012年

@jmad对。但是此示例确实使您直观地了解了log(n)。
Pratik Deoghare 2012年

@jmad我也可以使用算法来生成随机数,但我希望它尽可能简单。
Pratik Deoghare 2012年

8

是的,1n之间,但比n更接近1。什么是log n ?对数函数是指数的反函数。让我从指数开始,您应该对对数有一个更好的了解。log(n)1n1nlog(n)

考虑两个数字2 1002 1002乘以自己100倍。您可以尽力计算100个数字,但是可以计算2 100数字吗?我敢打赌你不能。为什么?2 100是一个很大的数字,它大于宇宙中所有原子的数目。反思一下。它是一个巨大的数字,它使您可以为每个原子命名(数字)。指甲中的原子数量可能约为数十亿个。 2 100应该足以容纳任何人(双关语:))。100210021002100100210021002100

现在,在两个数字2 100之间1002 100的对数(以2为底)。1002 100小得多。任何人都应该在家中拥有100种不同的物品。但是,对于宇宙来说2 100就足够了。在考虑对n n时,请考虑家与宇宙。10021001002100210021001002100log(n)n

指数和对数从哪里来?他们为什么对计算机科学如此感兴趣?您可能没有注意到,但是无处不在。您是否支付了信用卡利息?您只需为自己的房屋支付了费用(还算不错,但是曲线很合适)。我喜欢认为指数来自产品规则,但也欢迎其他人提供更多示例。您可能会问什么是产品规则?我会回答。

假设您有两个城市B,它们之间有两种选择。它们之间的路径数是多少?二。那是微不足道的。现在说,还有另一个城市C,您可以通过三种方式从BC。现在AC之间有多少条路径?六对吧 你是怎么得到的?你数了吗?还是您将它们相乘?无论哪种方式,都很容易看出两种方式都给出相似的结果。现在,如果您添加可以通过四种方式从C到达的城市D,那么AD之间有多少种方式ABCBCACDCAD?计数,如果你不相信我,但它是等于24。现在,如果有十个城市,并且从一个城市到下一个城市有两条路径,它们的排列方式就好像它们是一条直线。从头到尾有几条路?如果您不信任我,请乘以它们,但我会告诉您有2 10,即1024。看到,2 10是指数结果1010是对数2 10。与1024相比,10是一个很小的数字。2342421010242101010210101024

对数函数n等于n2 n(注意2是对数的底数)。如果您multipy 登录bñ 与自身b倍(注意,b是对数的底)你ñlog n 非常小,与n相比是如此之小,以至于它是房屋的大小,其中n是宇宙的大小。log2(n)nn2n2logb(n)bbnlog(n)nn

实际上,函数的执行与常量函数非常相似。它们的确以n增长,但是增长非常缓慢。如果您将程序优化为以耗时一天进行的对数时间运行,则可能会在几分钟内运行它。检查有关Euler项目的问题。log(n)n


3
虽然写得很好,但这个答案除了“ 确实很小” 之外几乎不包含任何信息。log(n)
拉斐尔

3
我试图给人以直观的印象。
拉维

5

为了继续您的主题,就像反复猜测x在列表中的位置,并被告知“较高”或“较低”(以索引表示)。O(logn)x

它仍然基于列表的大小,但是您只需要访问一部分元素。


4

如果我们有一个分治法,并且只对一个子问题进行一次递归调用,这是Master定理中的第二种情况,即非递归部分的时间复杂度为,则该算法的复杂度将为Θ lg k + 1 n Θ(lgkn)Θ(lgk+1n)

换句话说,当我们有一个分治法,对一个问题进行递归调用,该问题的大小是当前问题的常数,并且非递归部分中的时间为(常数),则该算法的运行时间将为lg nΘ(1)lgn

二进制搜索算法是经典的例子。


1

直觉是您可以将数字减半(例如n),然后再将其减为1就是O(lg n)。

为了进行可视化,请尝试将其绘制为二叉树,并通过解决此几何级数来计算级别数。

2^0+2^1+...+2^h = n

欢迎光临本站!您说的当然是正确的,但我看不出它对现有答案有什么帮助。已经有几个答案说对数是在达到1之前可以除以2的次数,而Ran的答案已经说对是具有n个叶子的二叉树的高度。lognn
大卫·里希比
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.