6.?無尾遞歸的實用方案
如前所述,斐波那契數列典型遞歸解法的時間復雜度為O(1.618n),呈指數增長,沒有實用價值。
如果妳仔細觀察遞歸調用過程,妳會發現calculate _ Fibonacci _ sequence(n-1)+calculate _ Fibonacci _ sequence(n-2)的二進制遞歸過程會有很多重復的中間結果。
然後,在遞歸過程中,將中間結果保存在壹個字典中,並在字典中檢查每個遞歸調用是否是具有相同參數的調用,如果是,則直接返回保存在字典中的值。
這樣,算法的時間復雜度降低到O(n)。通過緩存技術,時間復雜度被降低到可用水平。
開始編寫這個遞歸緩存裝飾器。裝飾器在Python中被廣泛使用,這便於在許多情況下進行模塊化級聯。
我們來試試效果,計數項目100。
原來卡住的情況沒了,結果幾秒就出來了。
好的,再試壹次計算項目1200。
堆棧溢出錯誤
這也是實用性的障礙。Python的默認堆棧空間並不大,只有1000。Python官方不推薦遞歸,盡量寫成叠代循環。而官方的想法是默認設置壹個小的堆棧空間。如果程序有太深的遞歸,可以在運行時早期暴露並重寫。
但是有時候遞歸的寫法真的很簡潔明了,在對效率沒有要求的時候還是可以用的。
那麽遞歸過程中溢出誤差的壹種解決方案是動態增加設定的極限值。
您可能會認為使用decorator是實現它的壹種優雅方式。
但是,當考慮到遞歸函數運行後應恢復recursionlimit的原始值時。
裝飾師不能簡單地獨自完成這個目標(如果您有任何好想法,請在下方留言討論_)
我通過傳入函數參數來實現這個解決方案。
讓我們試試效果。
運行時間與前面的示例相同,總時間為:0.012642秒。
問題解決
讓沒有實用價值的斐波那契數列的遞歸解法成為壹個可用的遞歸解法。
未完待續。
斐波那契數列的高效求解及時間復雜度分析系列4