1. 程式人生 > >斐波那契遞歸的優化及指數計算的優化

斐波那契遞歸的優化及指數計算的優化

ood n-2 1.9 start 遞歸 pre 指數 def art

import time


# 斐波那契傳統遞歸方法,屬於二路遞歸,重復計算數值,計算效率非常低,隨著n的增大,需要遞歸的次數將呈指數級增長
def bad_feibo(n):
    if n <= 1:
        return 1
    return bad_feibo(n-1)+bad_feibo(n-2)


# 在返回結果時,將前一個值順帶回來,這樣隨著n的增大,需要遞歸的次數呈線性增長,該優化將能大大提升遞歸效率
def good_feibo(n):

    def imp_feibo(n):
        if n <= 1:
            return (0, 1)
        a, b = imp_feibo(n-1)
        return (b, a+b)

    return sum(imp_feibo(n))


start = time.time()
a = bad_feibo(36)
print(‘bad_feibo: %s time: %s‘ % (a, time.time()-start))
start = time.time()
b = good_feibo(36)
print(‘good_feibo: %s time: %s‘ % (b, time.time()-start))

# bad_feibo: 24157817 time: 4.94177293777
# good_feibo: 24157817 time: 1.90734863281e-05


# 計算某個數的指數結果,隨著指數的增加,需要遞歸的次數呈線性增長,屬於線性遞歸
def bad_exp(x, r):

    def imp_exp(r):
        if r == 0:
            return 1
        return x*imp_exp(r-1)

    return imp_exp(r)


# 利用乘法的特性,隨著指數的增加,需要遞歸的次數呈現對數增長,屬於線性遞歸,在該例子中,優化的結果為計算時間少了一個數量級
def good_exp(x, r):

    def imp_exp(r):
        if r == 0:
            return 1
        if r == 1:
            return x
        mid = r // 2
        rst = imp_exp(mid)
        rst = rst*rst
        if r % 2 == 1:
            rst *= x
        return rst

    return imp_exp(r)


start = time.time()
a = bad_exp(2, 100)
print(‘bad_exp: %s time: %s‘ % (a, time.time()-start))
start = time.time()
b = good_exp(2, 100)
print(‘good_exp: %s time: %s‘ % (b, time.time()-start))

# bad_exp: 1267650600228229401496703205376 time: 5.50746917725e-05
# good_exp: 1267650600228229401496703205376 time: 5.96046447754e-06

斐波那契遞歸的優化及指數計算的優化