算法导论-求(Fibonacci)斐波那契数列算法对比
2014-09-10 18:52
260 查看
目录
1、斐波那契数列(Fibonacci)介绍
2、朴素递归算法(Naive recursive algorithm)
3、朴素递归平方算法(Naive recursive squaring)
4 、自底向上算法(Bottom-up)
5、 递归平方算法(Recursive squaring)
6、完整代码(c++)
7、参考资料
内容
1、斐波那契数列(Fibonacci)介绍
Fibonacci数列应该也算是耳熟能详,它的递归定义如上图所示。#ifndef FIBONACCI_HH #define FIBONACCI_HH struct Matrix2By2 { Matrix2By2 ( unsigned long long m00 = 0, unsigned long long m01 = 0, unsigned long long m10 = 0, unsigned long long m11 = 0 ) :m_00(m00), m_01(m01), m_10(m10), m_11(m11) { } unsigned long long m_00; unsigned long long m_01; unsigned long long m_10; unsigned long long m_11; }; class Fibonacci { public: unsigned long long Fibonacci_naive_reu(int n);//朴素递归算法 unsigned long long Fibonacci_bottom_up(int n);//自底向上算法 unsigned long long Fibonacci_recur_squar(int n);//递归平方算法 void MUL( unsigned long long MatrixA[2][2],unsigned long long MatrixB[2][2], unsigned long long MatrixResult[2][2] ); void Matrix_power(int n,unsigned long long result[2][2]); Matrix2By2 MatrixMultiply(const Matrix2By2& matrix1, const Matrix2By2& matrix2); Matrix2By2 MatrixPower(unsigned int n); unsigned long long Fibonacci_Solution3(unsigned int n); }; unsigned long long Fibonacci::Fibonacci_naive_reu(int n)//朴素递归算法 { int result[2] = {0,1}; if (n<2) //退出条件 return result ; return (Fibonacci_naive_reu(n-1)+ Fibonacci_naive_reu(n-2));//递归调用 } /************************************************************************/ /* 自底向上算法 */ // 时间复杂度T(n)=o(n) /************************************************************************/ unsigned long long Fibonacci::Fibonacci_bottom_up(int n)//自底向上算法 { int result[2] = {0, 1}; if(n < 2) return result ; unsigned long long fibNMinusN_1 = 1; unsigned long long fibNMinusN_2 = 0; unsigned long long fibN = 0; for(int i = 2; i <= n; ++ i) //从底到上逐次计算出数列值 { fibN = fibNMinusN_1 + fibNMinusN_2; fibNMinusN_2 = fibNMinusN_1; fibNMinusN_1 = fibN; } return fibN;//返回数组值 } /************************************************************************/ /* 两个 矩阵相乘 、结果矩阵保存在 MatrixResult[2][2]中 */ /************************************************************************/ void Fibonacci::MUL( unsigned long long MatrixA[2][2],unsigned long long MatrixB[2][2], unsigned long long MatrixResult[2][2] )//矩阵相乘 { for (int i=0;i<2 ;i++) { for (int j=0;j<2 ;j++) { MatrixResult[i][j]=0; for (int k=0;k<2 ;k++) { MatrixResult[i][j]=MatrixResult[i][j]+MatrixA[i][k]*MatrixB[k][j]; } } } } /************************************************************************/ /* 下面矩阵的n次幂,结果保存在 Result[2][2] */ // 矩阵的n次幂,采用分治法,与x的n 次方算法一致,时间复杂度T(n)=o(logn) // 1 1 // 1 0 /************************************************************************/ void Fibonacci::Matrix_power(int n,unsigned long long Result[2][2])//求矩阵幂 { unsigned long long AResult[2][2]; unsigned long long zResult1[2][2]; unsigned long long zResult2[2][2]; AResult[0][0]=1;AResult[0][1]=1;AResult[1][0]=1;AResult[1][1]=0; if (1==n) { Result[0][0]=1;Result[0][1]=1;Result[1][0]=1;Result[1][1]=0; } else if (n%2==0) { Matrix_power(n/2,zResult1); MUL(zResult1,zResult1,Result); } else if (n%2 == 1) { Matrix_power((n-1)/2,zResult1); MUL(zResult1,zResult1,zResult2); MUL(zResult2,AResult,Result); } } unsigned long long Fibonacci::Fibonacci_recur_squar(int n)//递归平方算法 { unsigned long long fib_result[2][2]; int result[2] = {0, 1}; if(n < 2) return result ; Matrix_power(n,fib_result); return fib_result[0][1]; } /************************************************************************/ /* 下面是网上copy的递归平方算法的代码 */ /************************************************************************/ /////////////////////////////////////////////////////////////////////// // Multiply two matrices // Input: matrix1 - the first matrix // matrix2 - the second matrix //Output: the production of two matrices /////////////////////////////////////////////////////////////////////// Matrix2By2 Fibonacci::MatrixMultiply ( const Matrix2By2& matrix1, const Matrix2By2& matrix2 ) { return Matrix2By2( matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10, matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11, matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10, matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11); } /////////////////////////////////////////////////////////////////////// // The nth power of matrix // 1 1 // 1 0 /////////////////////////////////////////////////////////////////////// Matrix2By2 Fibonacci::MatrixPower(unsigned int n) { Matrix2By2 matrix; if(n == 1) { matrix = Matrix2By2(1, 1, 1, 0); } else if(n % 2 == 0) { matrix = MatrixPower(n / 2); matrix = MatrixMultiply(matrix, matrix); } else if(n % 2 == 1) { matrix = MatrixPower((n - 1) / 2); matrix = MatrixMultiply(matrix, matrix); matrix = MatrixMultiply(matrix, Matrix2By2(1, 1, 1, 0)); } return matrix; } /////////////////////////////////////////////////////////////////////// // Calculate the nth item of Fibonacci Series using devide and conquer /////////////////////////////////////////////////////////////////////// unsigned long long Fibonacci::Fibonacci_Solution3(unsigned int n) { int result[2] = {0, 1}; if(n < 2) return result ; Matrix2By2 PowerNMinus2 = MatrixPower(n - 1); return PowerNMinus2.m_00; } #endif
Fibonacci.h
Fibonacci.cpp (主函数)
#include <iostream> #include <vector> #include <ctime> using namespace std; #include "Fibonacci.h" int main() { Fibonacci fib; clock_t startTime_For_Fibonacci_naive_reu ; clock_t endTime_For_Fibonacci_naive_reu ; clock_t startTime_For_Fibonacci_bottom_up ; clock_t endTime_For_Fibonacci_bottom_up ; clock_t startTime_For_Fibonacci_recur_squar1 ; clock_t endTime_For_Fibonacci_recur_squar1 ; clock_t startTime_For_Fibonacci_recur_squar2 ; clock_t endTime_For_Fibonacci_recur_squar2 ; startTime_For_Fibonacci_naive_reu=clock(); cout<<fib.Fibonacci_naive_reu(40)<<endl;//朴素递归算法 endTime_For_Fibonacci_naive_reu=clock(); startTime_For_Fibonacci_bottom_up=clock(); cout<<fib.Fibonacci_bottom_up(40)<<endl;//自底向上算法 endTime_For_Fibonacci_bottom_up=clock(); startTime_For_Fibonacci_recur_squar1=clock(); cout<<fib.Fibonacci_recur_squar(40)<<endl;//我自己编写的递归平方算法 endTime_For_Fibonacci_recur_squar1=clock(); startTime_For_Fibonacci_recur_squar2=clock(); cout<<fib.Fibonacci_Solution3(40)<<endl;//网上copy的递归平方算法 endTime_For_Fibonacci_recur_squar2=clock(); cout<<"朴素递归算法用时: "<<(endTime_For_Fibonacci_naive_reu-startTime_For_Fibonacci_naive_reu)/(1.0*CLOCKS_PER_SEC)<<"秒"<<endl; cout<<"自底向上算法用时: "<<(endTime_For_Fibonacci_bottom_up-startTime_For_Fibonacci_bottom_up)/(1.0*CLOCKS_PER_SEC)<<"秒"<<endl; cout<<"我自己编写的递归平方算法用时: "<<(endTime_For_Fibonacci_recur_squar1-startTime_For_Fibonacci_recur_squar1)/(1.0*CLOCKS_PER_SEC)<<"秒"<<endl; cout<<"网上copy的递归平方算法用时: "<<(endTime_For_Fibonacci_recur_squar2-startTime_For_Fibonacci_recur_squar2)/(1.0*CLOCKS_PER_SEC)<<"秒"<<endl; system("Pause"); return 0; }
输出:
结:朴素递归算法用时太多,实用价值不大,自底向上算法效率为线性,较高,平时用较多,递归平方算法效率为对数级,且编程可实现,实用价值很大。并且经过测试,当n值变很大后,递归平方算法效率明显高于自底向上算法效率。
7、参考资料
【1】http://zhedahht.blog.163.com/blog/static/25411174200722991933440/【2】http://blog.csdn.net/xyd0512/article/details/8220506
相关文章推荐
- 对比Fibonacci两种算法效率
- Fibonacci 斐波那契数列的几种写法、时间复杂度对比
- 斐波那契数列三种算法(fibonacci)
- String 匹配算法---第32章 分类: 算法导论 2011-03-03 10:43 193人阅读 评论(0) 收藏
- 三种强大的物体识别算法——SIFT/SURF、haar特征、广义hough变换的特性对比分析
- 算法导论笔记一:算法设计之分治法
- 人脸检测算法对比分析
- [Deeplearning]对比散度算法(CD算法)
- 斐波那契数列(一)--对比递归与动态规划(JAVA)
- 各种优化算法对比总结
- 算法导论(第三版)第二章 算法基础
- 各压缩算法对比
- 【算法02】3种方法求解斐波那契数列
- 三种强大的物体识别算法——SIFT/SURF、haar特征、广义hough变换的特性对比分析
- 斐波那契数列(Fibonacci)
- OpenCV特征点检测算法对比
- 机器学习的算法和普通《算法导论》里的算法有什么本质上的异同
- opencv自带人脸检测算法对比
- 斐波那契数列的几种实现与递归(Fibonacci Function and Recurrence)
- 斐波那契数列算法分析