




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、斐波那契數(shù)列算法分析 斐波那契數(shù)列算法分析背景:假定你有一雄一雌一對剛出生的兔子,它們在長到一個月大小時開始交配,在第二月結(jié)束時,雌兔子產(chǎn)下另一對兔子,過了一個月后它們也開始繁殖,如此這般持續(xù)下去。每只雌兔在開始繁殖時每月都產(chǎn)下一對兔子,假定沒有兔子死亡,在一年后總共會有多少對兔子?在一月底,最初的一對兔子交配,但是還只有1對兔子;在二月底,雌兔產(chǎn)下一對兔子,共有2對兔子;在三月底,最老的雌兔產(chǎn)下第二對兔子,共有3對兔子;在四月底,最老的雌兔產(chǎn)下第三對兔子,兩個月前生的雌兔產(chǎn)下一對兔子,共有5對兔子;如此這般計算下去,兔子對數(shù)分別是:1, 1, 2, 3, 5, 8, 13, 21, 34,
2、55,89, 144, .看出規(guī)律了嗎?從第3個數(shù)目開始,每個數(shù)目都是前面兩個數(shù)目之和。這就是著名的斐波那契(Fibonacci)數(shù)列。 有趣問題:1,有一段樓梯有10級臺階,規(guī)定每一步只能跨一級或兩級,要登上第10級臺階有幾種不同的走法?答:這就是一個斐波那契數(shù)列:登上第一級臺階有一種登法;登上兩級臺階,有兩種登法;登上三級臺階,有三種登法;登上四級臺階,有五種方法所以,1,2,3,5,8,13登上十級,有89種。2,數(shù)列中相鄰兩項的前項比后項的極限是多少,就是問,當n趨于無窮大時,F(xiàn)(n)/F(n+1)的極限是多少?答:這個可由它的通項公式直接得到,極限是(-1+5)/2,這個就
3、是所謂的黃金分割點,也是代表大自然的和諧的一個數(shù)字。 數(shù)學表示:Fibonacci數(shù)列的數(shù)學表達式就是:F(n) = F(n-1) + F(n-2)F(1) = 1F(2) = 1 遞歸程序1:Fibonacci數(shù)列可以用很直觀的二叉遞歸程序來寫,用C+語言的描述如下:long fib1(int n)if (n <= 2)return 1;elsereturn fib1(n-1) + fib1(n-2);看上去程序的遞歸使用很恰當,可是在用VC2005的環(huán)境下測試n=37的時候用了大約3s,而n=45的時候基本下樓打完飯也看不到結(jié)果顯然這種遞歸的效率太低了
4、!遞歸效率分析:例如,用下面一個測試函數(shù):long fib1(int n, int* arr)arrn+;if (n <= 2)return 1;elsereturn fib1(n-1, arr) + fib1(n-2, arr);這時,可以得到每個fib(i)被計算的次數(shù):fib(10) = 1fib(9) = 1fib(8) = 2fib(7) = 3fib(6) = 5fib(5) = 8fib(4) = 13fib(3) = 21fib(2) = 34fib(1) = 55fib(0) = 34可見,計算次數(shù)呈反向的Fibonacci數(shù)列,這顯然造成了大量重復計算。我們令T(N)
5、為函數(shù)fib(n)的運行時間,當N>=2的時候我們分析可知:T(N) = T(N-1) + T(N-2) + 2而fib(n) = fib(n-1) + fib(n-2),所以有T(N) >= fib(n),歸納法證明可得:fib(N) < (5/3)N當N>4時,fib(N)>= (3/2)N標準寫法:顯然這個O((3/2)N) 是以指數(shù)增長的算法,基本上是最壞的情況。其實,這違反了遞歸的一個規(guī)則:合成效益法則。合成效益法則(Compound interest rule):在求解一個問題的同一實例的時候,切勿在不同的遞歸調(diào)用中做重復性的工作。所以在上面的代碼中調(diào)
6、用fib(N-1)的時候?qū)嶋H上同時計算了fib(N-2)。這種小的重復計算在遞歸過程中就會產(chǎn)生巨大的運行時間。 遞歸程序2:用一叉遞歸程序就可以得到近似線性的效率,用C+語言的描述如下:long fib(int n, long a, long b, int count)if (count = n)return b;return fib(n, b, a+b, +count); long fib2(int n)return fib(n, 0, 1, 1);這種方法雖然是遞歸了,但是并不直觀,而且效率上相比下面的迭代循環(huán)并沒有優(yōu)勢。 迭代解法:Fibonacci數(shù)列用迭
7、代程序來寫也很容易,用C+語言的描述如下:/也可以用數(shù)組將每次計算的f(n)存儲下來,用來下次計算用(空間換時間)long fib3 (int n)long x = 0, y = 1;for (int j = 1; j < n; j+)y = x + y;x = y - x;return y;這時程序的效率顯然為O(N),N = 45的時候<1s就能得到結(jié)果。 矩陣乘法:我們將數(shù)列寫成:Fibonacci0 = 0,F(xiàn)ibonacci1 = 1Fibonaccin = Fibonaccin-1 + Fibonaccin-2 (n >= 2)可以將它寫成矩陣乘法形式:
8、將右邊連續(xù)的展開就得到:下面就是要用O(log(n)的算法計算:顯然用二分法來求,結(jié)合一些面向?qū)ο蟮母拍?,C+代碼如下:class Matrixpublic:long matr22; Matrix(const Matrix&rhs);Matrix(long a, long b, long c, long d);Matrix& operator=(const Matrix&);friend Matrix operator*(const Matrix& lhs, const Matrix& rhs)Matrix ret(0,0,0,0);ret.m
9、atr00 = lhs.matr00*rhs.matr00 + lhs.matr01*rhs.matr10;ret.matr01 = lhs.matr00*rhs.matr01 + lhs.matr01*rhs.matr11;ret.matr10 = lhs.matr10*rhs.matr00 + lhs.matr11*rhs.matr10;ret.matr11 = lhs.matr10*rhs.matr01 + lhs.matr11*rhs.matr11;return ret; Matrix:Matrix(long a, long b, long c, long d)this-&g
10、t;matr00 = a;this->matr01 = b;this->matr10 = c;this->matr11 = d; Matrix:Matrix(const Matrix &rhs)this->matr00 = rhs.matr00;this->matr01 = rhs.matr01;this->matr10 = rhs.matr10;this->matr11 = rhs.matr11; Matrix& Matrix:operator =(const Matrix &rhs)this->ma
11、tr00 = rhs.matr00;this->matr01 = rhs.matr01;this->matr10 = rhs.matr10;this->matr11 = rhs.matr11;return *this; Matrix power(const Matrix& m, int n)if (n = 1)return m;if (n%2 = 0)return power(m*m, n/2);elsereturn power(m*m, n/2) * m; long fib4 (int n)Matrix matrix0(1, 1, 1, 0);m
12、atrix0 = power(matrix0, n-1);return matrix0.matr00;這時程序的效率為O(log(N)) 。 公式解法:在O(1)的時間就能求得到F(n)了: 注意:其中x表示取距離x最近的整數(shù)。用C+寫的代碼如下:long fib5(int n)double z = sqrt(5.0);double x = (1 + z)/2;double y = (1 - z)/2;return (pow(x, n) - pow(y, n)/z + 0.5; 這個與數(shù)學庫實現(xiàn)開方和乘方本身效率有關的,我想應該還是在O(log(n)的效率。 總結(jié):上面給出
13、了5中求解斐波那契數(shù)列的方法,用測試程序主函數(shù)如下:int main()cout << fib1(45) << endl;cout << fib2(45) << endl;cout << fib3(45) << endl;cout << fib4(45) << endl;cout << fib5(45) << endl;return 0; 函數(shù)fib1會等待好久,其它的都能很快得出結(jié)果,并且相同為:1134903170。而后面兩種只有在n = 1000000000的時候會顯示
14、出優(yōu)勢。由于我的程序都沒有涉及到高精度,所以要是求大數(shù)據(jù)的話,可以通過取模來獲得結(jié)果的后4位來測試效率與正確性。另外斐波那契數(shù)列在實際工作中應該用的很少,尤其是當數(shù)據(jù)n很大的時候(例如:1000000000),所以綜合考慮基本普通的非遞歸O(n)方法就很好了,沒有必要用矩陣乘法。 附錄:程序全部源碼:#include <iostream>#include <vector>#include <string>#include <cmath>#include <fstream> using namespace std;&
15、#160;class Matrixpublic:long matr22; Matrix(const Matrix&rhs);Matrix(long a, long b, long c, long d);Matrix& operator=(const Matrix&);friend Matrix operator*(const Matrix& lhs, const Matrix& rhs)Matrix ret(0,0,0,0);ret.matr00 = lhs.matr00*rhs.matr00 + lhs.matr01*rhs.matr10;r
16、et.matr01 = lhs.matr00*rhs.matr01 + lhs.matr01*rhs.matr11;ret.matr10 = lhs.matr10*rhs.matr00 + lhs.matr11*rhs.matr10;ret.matr11 = lhs.matr10*rhs.matr01 + lhs.matr11*rhs.matr11;return ret; Matrix:Matrix(long a, long b, long c, long d)this->matr00 = a;this->matr01 = b;this->matr10 = c;th
17、is->matr11 = d; Matrix:Matrix(const Matrix &rhs)this->matr00 = rhs.matr00;this->matr01 = rhs.matr01;this->matr10 = rhs.matr10;this->matr11 = rhs.matr11; Matrix& Matrix:operator =(const Matrix &rhs)this->matr00 = rhs.matr00;this->matr01 = rhs.matr01;this->
18、;matr10 = rhs.matr10;this->matr11 = rhs.matr11;return *this; Matrix power(const Matrix& m, int n)if (n = 1)return m;if (n%2 = 0)return power(m*m, n/2);elsereturn power(m*m, n/2) * m; /普通遞歸long fib1(int n)if (n <= 2)return 1;elsereturn fib1(n-1) + fib1(n-2);/*上面的效率分析代碼long fib1(int n, int* arr)arrn+;if (n <= 1)return 1;elsereturn fib1(n-1, arr) + fib1(n-2, arr);*/ long fib(int n, long a, long b, int count)if (count = n)return b;return fib(n, b, a+b, +count);/一叉遞歸long
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年電子商務師(中級)考試試卷:電子商務數(shù)據(jù)分析工具應用
- 2025年大學英語六級口語流利度測試試卷
- 2025年保育員(初級)幼兒教育物聯(lián)網(wǎng)應用考試試卷
- 2025年統(tǒng)計學專業(yè)期末考試題庫:學術(shù)論文寫作規(guī)范與論文寫作技巧提升課程研討會效果評估試題
- 針灸課件介紹
- 金融數(shù)據(jù)分析技術(shù)課件
- 重癥患者護理課件
- 酗酒的危害教學課件
- 2025年高端小型車項目可行性研究報告
- 公路護欄項目可行性研究報告立項模板
- 蘭州彤輝商貿(mào)有限公司肅南縣博懷溝一帶銅鐵礦礦產(chǎn)資源開發(fā)與恢復治理方案
- 零星維修項目服務方案
- 檢驗檢測機構(gòu)質(zhì)量管理課件
- 2023年甲流流感中醫(yī)藥防治方案護理課件
- 光伏并網(wǎng)前單位工程驗收報告-2023
- 傳統(tǒng)木偶戲的歷史與發(fā)展
- 代數(shù)的魅力與技巧
- 重癥肺炎個案護理查房
- 最全海外常駐和出差補助管理規(guī)定
- 教育部中小學心理健康教育特色學校標準
- 工程材料耗用(核算)表
評論
0/150
提交評論