----------------------android培训、java培训、期待与您交流! ----------------------
一、实验环境
操作系统:Windows 7 Ultimate 64bit SP1
处理器:Intel Core i7-2630QM CPU @ 2.00GHz
内存:8GB (DDR3 1333MHz)
编程语言Visual C# 4.0
编译环境Visual Studio 2010 + Release + Optimize Code
二、 实验方法
由Fibonacci数列的定义,我们有如下的递推式:Fn=Fn-1 + Fn-1
通过定义来计算数列的Fn需要的时间复杂度为O(n),空间复杂度O(1)。
而Fibonacci数列还能通过如下的矩阵方法计算:
即要计算数列的Fn+1只需要计算A^n,而A^n能够通过分治法在时间复杂度O(lgn)的情况下计算出来。
实验中需要注意的地方是,如果使用无符号长整数数据类型来计算Fn,那么从第48项开始数据就会溢出,
即使使用无符号长整数数据类型,从第94项开始数据也会溢出。因此如果只是使用基本数据类型,
那么后面的项将无法正确计算。所以实验还需要实现一个能够处理大整数的数据类型,在实验中我们
使用了一个无符号长整数动态数组来实现一个基数为10^8的大整数类,数组下标为0的元素则对应了
“个”位,以此类推。这个大整数类实现了加法和乘法,时间复杂度分别为O(n),O(n^2),而乘法还能改进
的地方,比如使用分治法能够将时间复杂度改进到O(n^ log2^3),而使快速傅里叶变换则恩给你改进到
O(nlgn)
三、实验结果
图1 实验数据
虽然前面提及过用递推法和矩阵法求Fibonacci数列Fn的时间复杂度分别为O(n),O(lgn),但是从图表
中能够看出两种方法运行时间的曲线并不是像分析的那样。这是因为分析的时候是假设数的加法或是
乘法都是能够在O(1)时间复杂度内完成的,然后实际的情况是我们必须使用大整数类才能保证计算的正确,
而使用大整数类进行运算的时候,加法和乘法都将不能够在O(1)时间复杂度内完成的,在本实验中实现的
大整数类加法和乘法的时间复杂度分别为O(n),O(n^2),与数的长度有关。因此两种方法运行时间的曲线
也就不能像原先分析的那样,而是呈现图表中这样的曲线。
---------------------- android培训、java培训、期待与您交流! ----------------------