大写符号的运行时间和懒惰的评估

时间:2012-11-29 06:28:55

标签: python algorithm time-complexity

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)吗?我只知道如何根据我以前见过的例子进行猜测。 :(

1 个答案:

答案 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)