1. 程式人生 > >Fibonacci的幾種方法討論

Fibonacci的幾種方法討論

1.用定義的遞迴演算法
f(n)=f(n-1)+f(n-2)
指數級別,因為不斷的重複計算,很多冗餘

public static int Fibonacci1(int n)
	{	if (n<=1) return n;
		return Fibonacci1(n-1)+Fibonacci1(n-2);
	}

2.用定義的迭代演算法
線性,技巧是存下來,和動態規劃的思想有些一致。

public static int Fibonacci2(int n)
	{	int a=0;int b=1;
	if (n==0)  return 0;
	while(n>1)
	{
		int
c=a; a=b; b=c+b; n--; } return b; }

3.公式法
f(n)為Φ^n/√5取最近的整數,Φ=(1+√5)/2.
這種方法必須注意精度
用double來計算時會發現n=37時答案已經不準了

public static int Fibonacci3(int n)
	{	double a=(1+Math.sqrt(5))/2;
	int m=(int)(Math.pow(a, n)/Math.sqrt(5));
	if((n&1)==1)   m++;//當n為奇數時,是取整加一
	return     m;
	}

這種方法效率取決於指數的計算。如果是直接相乘是線性的,如果用減半的方法,可以得到對數級別的。
4.使用某個等式

(1) { f

( n 1 ) f ( n ) f ( n ) f ( n + 1 ) } = { 0 1 1 1 } n , n &gt; = 1 \left\{ \begin{matrix} f(n-1)&amp;f(n) \\ f(n) &amp;f(n+1)\\ \end{matrix} \right\} \tag{1}= \left\{ \begin{matrix} 0&amp;1 \\ 1 &amp; 1\\ \end{matrix} \right\}^n,n&gt;=1

對數級別的

//矩陣乘法	  兩個方陣a、b乘積
		public static int[][]Matrix_Multiply(int a[][],int b[][],int n)
		{int c[][]=new int[n][n];
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
			c[i][j]+=a[i][k]*b[k][j];
		return c;	
		}
		
//矩陣快速冪(log n)
	public static int Fibonacci4(int n)
	{	int multi[][]= {{1,0},{0,1}};//單位矩陣
	int x[][]= {{0,1},{1,1}};
	while(n>0)
	{
		if((n&1)==1)   			
		multi=Matrix_Multiply(multi,x,2);
		
		x=Matrix_Multiply(x,x,2);
		n>>=1;//相當於n=n/2
	}
	return multi[0][1];	
	}