菲波那切数列 :矩阵加速递推 矩阵快速幂

package Fibonacci_accelerate;
//Fibonacci:f(0) = 0 ,f(1) = 1,f(n+1) = f(n) + f(n-1);
	//矩阵快速递推:
	/*(因为最后*[1,0]'就相当于保留a矩阵的第一列,所以最后的*a[1,0]'就可以省略了)
	 *|f(n+1)|  = |1 1| * | f(n) | = ... = |1 1|^n * |f(1)| =|1 1|^n * |1| 
	 *|f(n)|      |1 0|   |f(n-1)|         |1 0|	 |f(0)|  |1 0|	   |0|
	 *so:
	 * 	define:
	 *  n=0 a(0)=|1 1|^0 = |1 0|  ,ans(0)= a(0)[0][1] = 0;
	 ************|1 0|     |0 1|
	 *      
	 *	n=1 a(1)=|1 1|^1          ,ans(1)= a(0)[0][1] = 1;
	 ****************|1 0|
	 * 
	 *  n=i a(i)=|1 1|^i
	 ************|1 0|
	 *  
	 *  ans(n) =a(n)[0,1], 其中a(n)[0,0]为f(n+1),a(n)[0,1]为f(n)
	 *				 	   		   			       
	 */
	//快速幂:
	/* 
	 * a^n = ( a^(n/2) )^2 =  [a^(n/2)]^2, n % 2 = 0 || a*([a^(n/2)]^2), n % 2 = 1
	 * so:
	 * int quickpower(int a, int n){
	 * 	if (n = 0) return 0; 
	 * 	if (n % 2)==0 return quickpower(a,n/2)*quickpower(a,n/2);
	 * 	else return a*quickpower(a,n/2)*quickpower(a,n/2);
	 * }
	 * 
	 * 
	 */
	//矩阵快速幂
	/*对于A^n,可将改写成2进制,如n = 156(10) = 10011100(2)
	 * so ans = A^(2^7) * A^(2^4) * A^(2^3) * A^(2^2)
	 * 
	 * While(n){
	 * 	if(n&1==1) ans = ans*A;
	 * 	A = A*A;
	 *  n= n>>1;//n= n / 2;
	 * }
	 * 
	 */
public class Fibonacci {
	public static long[][] multiply(long a[][],long b[][]){
		if(a == null|| b==null ) return null;
		int x =a.length,y=a[0].length;
		long[][] result = new long[x][y];
		
		for(int i=0; i<a.length;i++){
			for(int j=0;j<b[0].length;j++){
				long temp = 0;
				for(int k=0;k<b.length;k++){
					temp = temp + a[i][k]*b[k][j]; 
				}
				result[i][j] = temp;
			}
		}
		return result;
	}
	
	public static long[][] quickPowerMmatrix_Iteration(long[][] A,int n){
		long[][] result = new long[A.length][A[0].length];
		for(int i= 0;i<A.length;i++){
			result[i][i] = 1; //初始化成单位阵
		}
		while(n>0){
			if((n&1)==1) result = multiply(result, A);
			n=n>>1;
			A=multiply(A, A);
		}		
		return result;
	}
	
	public static long[][] fib_MatrixAccelerate_Iteration(int n){
		if(n==0) {
			long[][] ans = {{1,0},{0,1}};
			return ans;
		}
		if(n==1){
			long[][] ans = {{1,1},{1,0}};
			return ans;
		}
		long[][] ans={{1,1},{1,0}};
		return quickPowerMmatrix_Iteration(ans, n);
	}
	
	public static long[][] fib_MatrixAccelerate_Recursion(int n){
		if(n==0) {
			long[][] ans = {{1,0},{0,1}};
			return ans;
		}
		if(n==1){
			long[][] ans = {{1,1},{1,0}};
			return ans;
		}
		long[][] ans = null;
		if(n%2==0) {
			ans = multiply(fib_MatrixAccelerate_Recursion(n/2), fib_MatrixAccelerate_Recursion(n/2));
		}
		if(n%2==1){
			long[][] temp = {{1,1},{1,0}};
			ans = multiply(temp, multiply(fib_MatrixAccelerate_Recursion(n/2), fib_MatrixAccelerate_Recursion(n/2)));
		}
		return ans;
	}
	
	public static void main(String[] args){
		//0、1、1、2、3、5、8、13、21
		//0 1 2  3  5
		
		for(int k = 0;k<20;k++){
			long[][] ans1 = fib_MatrixAccelerate_Iteration(k);
			long[][] ans2 = fib_MatrixAccelerate_Iteration(k);
			System.out.println("Iteration:"+ans1[0][1]+"||Recursion:"+ans2[0][1]);
		}
		
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值