def foo(x):
if x > 5:
return foo(x–1) – foo(x-1)
else:
return 11
def bar(a,b):
if (b > 0):
return bar( bar(a, b+1) , b-1 )
else:
return 0
如何在Big O notation
中找到运行时间,以及延迟评估(在需要值之前不评估表达式)会影响这个?
由于单个递归调用,第一个是O(n)
吗?由于另一个递归调用中的递归调用,第一个是O(n^2)
吗?我只知道如何根据我以前见过的例子进行猜测。 :(
答案 0 :(得分:3)
foo()
为O(2^n)
(假设interpeter没有缓存优化)。bar()
为O(infinity)
(永不终止),O(n)
为懒惰评估 <强>说明:强>
每个foo(n)
调用2次f(n-1)
调用,因此您将获得复杂性函数:
T(n) = T(n-1) + T(n-1) = T(n-2) + T(n-2) + T(n-2) + T(n-2) = ... = 2^(n-5)*T(5)
(...
部分可以使用mathematical induction)
bar(n)
处于无限循环中,因为假定b>0
- 它将以b+1
递归调用 - 这也将满足约束b>0
。通过归纳,您可以获得所有b>0
bar()
b'>b
bar()
的额外调用 - 这会导致无限次O(infinity)
的调用 - 因此{{1} }
使用延迟评估,第二种方法(bar()
)变为O(n)
。
这是因为无限重新发生只是为了评估a
- 但是,因为a
从未真正使用过 - 所以不需要评估参数a
的表达式,并且由于b
减少了每次递归调用 - 您得到O(n)
T(n) = T(n-1) + T(n-1)
的正式证明在O(2^n)
:
基数: T(5)= CONST
为每个T(k) <= CONST * 2^k
假设:k<n
的证明:强>
T(n) = T(n-1) + T(n-1) <= (assumption) <= CONST* 2^(n-1) + CONST* 2^(n-1) =
= CONST*2*2^(n-1) = CONST * 2^n
从数学归纳中我们可以得出结论,假设是正确的T(n)
在O(2^n)