Fibonacci
数列
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Fibonacci
背景知识

斐波那契:
比萨德列奥纳多,又称斐波那契(
Leonardo Pisano ,Fibonacci, Leonardo Bigollo
1175
-1250
年),意大利数学家,西方第一个研究斐波那契数,并将现代书写数和乘数的位值表示法系统引入欧洲。

Fibonacci
引出

斐波那契
在《算盘书》中提出了一个有趣的兔子问题:一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔都不死,那么一年以后可以繁殖多少对兔子?

我们不妨拿新出生的一对小兔子分析一下:第一个月小兔子没有繁殖能力,所以还是一对;两个月后,生下一对小兔总数共有两对; 三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对;

类推表如下:

              
经过月数

0

1

2

3

4

5

6

7

8

9

10

11

12

              
幼仔对数

1

0

1

1

2

3

5

8

13

21

34

55

89

              
成兔对数

0

1

1

2

3

5

8

13

21

34

55

89

144

              
总体对数

1

1

2

3

5

8

13

21

34

55

89

144

233

 

      
从一年的总体对数中可以发现
,
从第二个月开始,其数量是前两个月的数量的和,所以得出递推公式为:

F(n)=F(n-1)+F(n-2)(n>=2)     (1)

Fibonacci
数列的性质

1.
F(n)=F(n-1)+F(n-2)

2. 
其任意一项平方数为其前项和后项的积加一或者减一

    F(n)*F(n)=F(n-1)*F(n+1)+/-1

3.
任取相邻的四个斐波那契数,中间两数之积(内积)与两边两数之积(外积)相差
1

Fibonacci
数列的程序实现

1.  递归实现 

InBlock.gifstatic int Fib1(int n)
InBlock.gif                {
InBlock.gif                        int []result = new int[]{ 0, 1 };
InBlock.gif                        if(n<2) return result[n];
InBlock.gif                        return Fib1(n-1)+Fib1(n-2);
InBlock.gif                }
 
 
2. 非递归实现(迭代法)

InBlock.gifstatic int Fib2(int n)    
InBlock.gif                {
InBlock.gif                        int[] result = new int[] { 0, 1 };
InBlock.gif
InBlock.gif                        if (n < 2) return result[n];
InBlock.gif
InBlock.gif                        int n1=0,n2=1,retTemp=0;
InBlock.gif
InBlock.gif                        for (int i = 2; i <=n; i++)
InBlock.gif                        {
InBlock.gif                                retTemp = n1 + n2;
InBlock.gif                                n1 = n2;
InBlock.gif                                n2 = retTemp;
InBlock.gif                        }
InBlock.gif                        return retTemp;
InBlock.gif                }
 
2. 创新法(矩阵公式)

存在一个Fibonacii的矩阵恒等式,其形式如下所示:

        对于F(n)来说,只需要求右边的矩阵的n次幂,然后F(n-1)即为所求结果的第一行第一列的值。

       对于右边的矩阵的n次幂可以将n化为:

InBlock.gif
public
static Matrix MatrixPower(
int n)
InBlock.gif                        {
InBlock.gif                                Debug.Assert(n > 0);
InBlock.gif                                Matrix matrix =
new Matrix();
InBlock.gif
InBlock.gif                                
if (n == 1)
InBlock.gif                                {
InBlock.gif                                        
return matrix=
new Matrix(1,1,1,0);
InBlock.gif                                }
InBlock.gif                                
if(n%2==0)
InBlock.gif                                {
InBlock.gif                                        matrix = MatrixPower(n / 2);
InBlock.gif                                        matrix = MatrixMuti(matrix, matrix);    
InBlock.gif                                }
InBlock.gif                                
if (n % 2 == 1)
InBlock.gif                                {
InBlock.gif                                        matrix = MatrixPower((n-1) / 2);
InBlock.gif                                        matrix = MatrixMuti(matrix, matrix);
InBlock.gif                                        matrix = MatrixMuti(matrix,
new Matrix(1, 1, 1, 0));
InBlock.gif                                }
InBlock.gif                                
return matrix;
InBlock.gif                        }
 
 
利用
Fibonacci
矩阵恒等式方法就
Fibonacci
数列:
InBlock.gif
internal
class MaxtrixBy
InBlock.gif                {
InBlock.gif
InBlock.gif                        
public
struct Matrix
InBlock.gif                        {
InBlock.gif                                
public
int m00, m01, m10, m11;
InBlock.gif                                
public Matrix(
int _m00,
int _m01,
int _m10,
int _m11)    
InBlock.gif                                {
InBlock.gif                                        m00 = _m00;
InBlock.gif                                        m01 = _m01;
InBlock.gif                                        m10 = _m10;
InBlock.gif                                        m11 = _m11;
InBlock.gif                                }
InBlock.gif                        }
InBlock.gif                        
public
static Matrix MatrixMuti(Matrix m1, Matrix m2)
InBlock.gif                        {
InBlock.gif                                
return
new Matrix(m1.m00 * m2.m00 + m1.m10 * m2.m01, m1.m00 * m2.m10 + m1.m10 * m2.m11,
InBlock.gif                                                            m1.m10 * m2.m00 + m1.m11 * m2.m01, m1.m10 * m2.m00 + m1.m11 * m2.m11);
InBlock.gif                                                            
InBlock.gif                        }
InBlock.gif    
InBlock.gif                        
public
static Matrix MatrixPower(
int n)
InBlock.gif                        {
InBlock.gif                                Debug.Assert(n > 0);
InBlock.gif                                Matrix matrix =
new Matrix();
InBlock.gif
InBlock.gif                                
if (n == 1)
InBlock.gif                                {
InBlock.gif                                        
return matrix=
new Matrix(1,1,1,0);
InBlock.gif                                }
InBlock.gif                                
if(n%2==0)
InBlock.gif                                {
InBlock.gif                                        matrix = MatrixPower(n / 2);
InBlock.gif                                        matrix = MatrixMuti(matrix, matrix);    
InBlock.gif                                }
InBlock.gif                                
if (n % 2 == 1)
InBlock.gif                                {
InBlock.gif                                        matrix = MatrixPower((n-1) / 2);
InBlock.gif                                        matrix = MatrixMuti(matrix, matrix);
InBlock.gif                                        matrix = MatrixMuti(matrix,
new Matrix(1, 1, 1, 0));
InBlock.gif                                }
InBlock.gif                                
return matrix;
InBlock.gif                        }
InBlock.gif
InBlock.gif                        
public
static
int Fib3(
int n)
InBlock.gif                        {
InBlock.gif                                
int[] result =
new
int[] { 0, 1 };
InBlock.gif                                
if(n<2)
return result[n];
InBlock.gif                            
// MaxtrixBy matrixby=new MaxtrixBy();
InBlock.gif                                Matrix m = MaxtrixBy.MatrixPower(n - 1);
InBlock.gif                                
return m.m00;
InBlock.gif                        }
InBlock.gif                }
 
3
运行效率分析

 

递归表示

迭代法

矩阵恒等式

时间复杂度

O(2 exp n)

O(n)

O(logn)