Python 对于计算次数随n振荡的递归函数,其大O复杂度是多少?
我有一个找到指数的函数,但我对函数的复杂性感到困惑 功能:Python 对于计算次数随n振荡的递归函数,其大O复杂度是多少?,python,algorithm,big-o,complexity-theory,Python,Algorithm,Big O,Complexity Theory,我有一个找到指数的函数,但我对函数的复杂性感到困惑 功能: def expo(number, exponent): if exponent == 0: return 1 elif exponent % 2 == 0: val = expo(number, exponent / 2) return val * val else: return number * expo(number, exponent -
def expo(number, exponent):
if exponent == 0:
return 1
elif exponent % 2 == 0:
val = expo(number, exponent / 2)
return val * val
else:
return number * expo(number, exponent - 1)
我试图根据指数计算并绘制计算次数的图表,结果如下:
图形:
指数:计算:
def expo(number, exponent):
if exponent == 0:
return 1
elif exponent % 2 == 0:
val = expo(number, exponent / 2)
return val * val
else:
return number * expo(number, exponent - 1)
1:2,2:3,3:4,4:4,5:5,6:5,7:6,8:5,9:6,10:6,11:7,12:6,13:7,14:7,15:8,16:6,17:7,18:7,19:8,20:7,21:8,22:8,23:9,24:7,25:8,26:8,27:9,28:8,29:9,30:9
正如您所看到的,计算的数量是振荡的,我认为Big-O符号将不是线性或二次的。我认为它将像一个多重多项式,其表示形式如下
<我是对还是错了O(N)表示法?< P>,你可以考虑最坏情况下的算法。因此,如果
T(n)
是算法的时间,最坏情况是T(n)=T(n-1)+c
(c
是比较、求和、调用函数等的常量)。因此,T(n)=O(n)
另外,声明我认为O(n)不是线性的或二次的
没有意义。如果一个函数在O(n)
中,则表示它最多是线性的。因此,它不可能是二次的
现在,您可以更仔细地研究时间复杂度计算,并尝试找到复杂度的严格界限。因为,在两个连续递归中至少有一次,我们将得到
指数的偶数值(因为我们有-1
,如果指数是奇数),因此指数达到1
,计算的日志(n)
(因为在每2个连续的递归中,指数至少会被2除)。因此,T(n)
的紧界是O(log(n))
这是一种众所周知的算法,称为快速指数化(有时是平方和乘法),其复杂性是O(log(n))
。维基百科有一整页的内容:
但是如果你不知道这些信息,一种想法是重写你的算法,这样你就可以很容易地找到递推公式。
主要的困难在于奇数和偶数的处理过程不同。诀窍是将它们组合在一起,只进行一次递归调用
def expo(number, exponent):
if exponent == 0:
return 1
elif exponent % 2 == 0:
val = expo(number, exponent / 2)
return val * val
else:
return number * expo(number, exponent - 1) # exponent - 1 is even !
可以重写
def expo(number, exponent):
if exponent == 0:
return 1
elif exponent % 2 == 0:
val = expo(number, exponent / 2)
return val * val
else:
return number * expo(number, (exponent - 1) / 2) ** 2
现在您可以看到,在算法的每一步,指数
被(粗略地)除以2(这不再取决于它的奇偶性),因此复杂性是log(n)
这看起来像是快速求幂算法,它是O(log(n))复杂度:也许你应该用对数标度绘制横坐标以获得一些见解。@pLOPeGG是的,我认为这是相同的算法,虽然我不知道复杂度是如何计算的,但它仍然回答了我的问题,谢谢你是对的O(log(n))