斐波那契數(shù)列算法分析_第1頁(yè)
斐波那契數(shù)列算法分析_第2頁(yè)
斐波那契數(shù)列算法分析_第3頁(yè)
斐波那契數(shù)列算法分析_第4頁(yè)
斐波那契數(shù)列算法分析_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、斐波那契數(shù)列算法分析 斐波那契數(shù)列算法分析背景:假定你有一雄一雌一對(duì)剛出生的兔子,它們?cè)陂L(zhǎng)到一個(gè)月大小時(shí)開始交配,在第二月結(jié)束時(shí),雌兔子產(chǎn)下另一對(duì)兔子,過(guò)了一個(gè)月后它們也開始繁殖,如此這般持續(xù)下去。每只雌兔在開始繁殖時(shí)每月都產(chǎn)下一對(duì)兔子,假定沒有兔子死亡,在一年后總共會(huì)有多少對(duì)兔子?在一月底,最初的一對(duì)兔子交配,但是還只有1對(duì)兔子;在二月底,雌兔產(chǎn)下一對(duì)兔子,共有2對(duì)兔子;在三月底,最老的雌兔產(chǎn)下第二對(duì)兔子,共有3對(duì)兔子;在四月底,最老的雌兔產(chǎn)下第三對(duì)兔子,兩個(gè)月前生的雌兔產(chǎn)下一對(duì)兔子,共有5對(duì)兔子;如此這般計(jì)算下去,兔子對(duì)數(shù)分別是:1, 1, 2, 3, 5, 8, 13, 21, 34,

2、55,89, 144, .看出規(guī)律了嗎?從第3個(gè)數(shù)目開始,每個(gè)數(shù)目都是前面兩個(gè)數(shù)目之和。這就是著名的斐波那契(Fibonacci)數(shù)列。有趣問題:1,有一段樓梯有10級(jí)臺(tái)階,規(guī)定每一步只能跨一級(jí)或兩級(jí),要登上第10級(jí)臺(tái)階有幾種不同的走法?答:這就是一個(gè)斐波那契數(shù)列:登上第一級(jí)臺(tái)階有一種登法;登上兩級(jí)臺(tái)階,有兩種登法;登上三級(jí)臺(tái)階,有三種登法;登上四級(jí)臺(tái)階,有五種方法所以,1,2,3,5,8,13登上十級(jí),有89種。2,數(shù)列中相鄰兩項(xiàng)的前項(xiàng)比后項(xiàng)的極限是多少,就是問,當(dāng)n趨于無(wú)窮大時(shí),F(xiàn)(n)/F(n+1)的極限是多少?答:這個(gè)可由它的通項(xiàng)公式直接得到,極限是(-1+5)/2,這個(gè)就是所謂的黃金

3、分割點(diǎn),也是代表大自然的和諧的一個(gè)數(shù)字。數(shù)學(xué)表示:Fibonacci數(shù)列的數(shù)學(xué)表達(dá)式就是:F(n) = F(n-1) + F(n-2)F(1) = 1F(2) = 1遞歸程序1:Fibonacci數(shù)列可以用很直觀的二叉遞歸程序來(lái)寫,用C+語(yǔ)言的描述如下:long fib1(int n)if (n = 2)return 1;elsereturn fib1(n-1) + fib1(n-2);看上去程序的遞歸使用很恰當(dāng),可是在用VC2005的環(huán)境下測(cè)試n=37的時(shí)候用了大約3s,而n=45的時(shí)候基本下樓打完飯也看不到結(jié)果顯然這種遞歸的效率太低了!遞歸效率分析:例如,用下面一個(gè)測(cè)試函數(shù):long fi

4、b1(int n, int* arr)arrn+;if (n =2的時(shí)候我們分析可知:T(N) = T(N-1) + T(N-2) + 2而fib(n) = fib(n-1) + fib(n-2),所以有T(N) = fib(n),歸納法證明可得:fib(N) 4時(shí),fib(N)= (3/2)N標(biāo)準(zhǔn)寫法:顯然這個(gè)O((3/2)N) 是以指數(shù)增長(zhǎng)的算法,基本上是最壞的情況。其實(shí),這違反了遞歸的一個(gè)規(guī)則:合成效益法則。合成效益法則(Compound interest rule):在求解一個(gè)問題的同一實(shí)例的時(shí)候,切勿在不同的遞歸調(diào)用中做重復(fù)性的工作。所以在上面的代碼中調(diào)用fib(N-1)的時(shí)候?qū)嶋H上

5、同時(shí)計(jì)算了fib(N-2)。這種小的重復(fù)計(jì)算在遞歸過(guò)程中就會(huì)產(chǎn)生巨大的運(yùn)行時(shí)間。遞歸程序2:用一叉遞歸程序就可以得到近似線性的效率,用C+語(yǔ)言的描述如下: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)勢(shì)。迭代解法:Fibonacci數(shù)列用迭代程序來(lái)寫也很容易,用C+語(yǔ)言的描述如下:/也可以用數(shù)組將每次計(jì)算

6、的f(n)存儲(chǔ)下來(lái),用來(lái)下次計(jì)算用(空間換時(shí)間)long fib3 (int n)long x = 0, y = 1;for (int j = 1; j n; j+)y = x + y;x = y - x;return y;這時(shí)程序的效率顯然為O(N),N = 45的時(shí)候= 2)可以將它寫成矩陣乘法形式:將右邊連續(xù)的展開就得到:下面就是要用O(log(n)的算法計(jì)算:顯然用二分法來(lái)求,結(jié)合一些面向?qū)ο蟮母拍睿珻+代碼如下:class Matrixpublic:long matr22;Matrix(const Matrix&rhs);Matrix(long a, long b, long c,

7、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;ret.matr01 = lhs.matr00*rhs.matr01 + lhs.matr01*rhs.matr11;ret.matr10 = lhs.matr10*rhs.matr00 + lhs.matr11*rhs.matr10;r

8、et.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;this-matr11 = d;Matrix:Matrix(const Matrix &rhs)this-matr00 = rhs.matr00;this-matr01 = rhs.matr01;this-matr10 = rhs.matr10;this-matr11 = r

9、hs.matr11;Matrix& Matrix:operator =(const Matrix &rhs)this-matr00 = 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 (i

10、nt n)Matrix matrix0(1, 1, 1, 0);matrix0 = power(matrix0, n-1);return matrix0.matr00;這時(shí)程序的效率為O(log(N)) 。公式解法:在O(1)的時(shí)間就能求得到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; 這個(gè)與數(shù)學(xué)庫(kù)實(shí)現(xiàn)開方和乘方本身效率有關(guān)的,我想應(yīng)該還

11、是在O(log(n)的效率??偨Y(jié):上面給出了5中求解斐波那契數(shù)列的方法,用測(cè)試程序主函數(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會(huì)等待好久,其它的都能很快得出結(jié)果,并且相同為:1134903170。而后面兩種只有在n = 1000000000的時(shí)候會(huì)顯示出優(yōu)勢(shì)。由于我的程序都沒有涉及到高精度,所以要是求大數(shù)據(jù)的話,可以通過(guò)取模來(lái)獲得結(jié)果的后4位來(lái)測(cè)試效率與正確性。另外斐波那契數(shù)列在實(shí)際工作

12、中應(yīng)該用的很少,尤其是當(dāng)數(shù)據(jù)n很大的時(shí)候(例如:1000000000),所以綜合考慮基本普通的非遞歸O(n)方法就很好了,沒有必要用矩陣乘法。附錄:程序全部源碼:#include #include #include #include #include using namespace std;class Matrixpublic:long matr22;Matrix(const Matrix&rhs);Matrix(long a, long b, long c, long d);Matrix& operator=(const Matrix&);friend Matrix operator*(co

13、nst Matrix& lhs, const Matrix& rhs)Matrix ret(0,0,0,0);ret.matr00 = 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 re

14、t;Matrix:Matrix(long a, long b, long c, long d)this-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-matr00 =

15、 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 fib1(int n)if (n = 2)return 1;elsereturn fib1(n-1) + fib1(n-2);/*上面的效

16、率分析代碼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 fib2(int n)return fib(n, 0, 1, 1);/非遞歸方法O(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(log(n)long fib4 (int n)Matrix matrix0(1, 1, 1, 0);matrix0 = power(matrix0, n-1);return matrix0.matr00;/公

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論