Three kinds of solution (simple recursion, dynamic programming, mathematical induction) and algorithm analysis Fibonacci columns

<Introduction to Algorithms> article from the open class Netease third talk of divide and conquer. I use to divide and conquer with a new understanding of Fibonacci number, also known as golden columns, F0 = 0, F1 = 1, the Fn = F (the n--1) + F (the n--2) ( n> = 2, n∈N *)

       Now I will use the Java (yes, but also Java, but I think no problem, algorithms Well, focusing on ideological) respectively to achieve these three methods. Later video to see half, made the time is now to solve this problem using a simple recursive method, there are many repetitive sub-problems, then this is in line with the basic idea of dynamic programming, and can be solved using a bottom-up order, save the result of sub-problems . The algorithm to do this time is: theta (n)

       1. simple recursive: self-directed problem solving down, resulting in a lot of repetition to solve

       2. Dynamic Programming: Exactly should be a "dynamic programming" bottom-up ideas from solution.

       3. mathematical induction (even by linear algebra matrix formula)

       Set Fn n th Fibonacci number , then there Theorem:

       Proof: When n = 1, F0 = 0, F1 = 1, F2 = 2, namely:

       So assuming that the theorem is true , it will have to be brought into the n-1 expression:

       which is:

       Because the equation

       Permanent establishment, then hypothesis.

       Such Fibonacci number will be converted into a power problem n, then n algorithm time power problem why not , but what? May be used herein divide and conquer problem solving power of n, the number n may be equal multiplicative into left and right parts (even if d n / 2 and n / 2, the odd words (n-1) / 2 and (N- 1) / 2). There:

N this number even by simply dividing times.

       code show as below:

package com.wly.algorithmproblem;

/**
 * 解斐波拉契数列问题,使用三种方法:朴素递归解法、自底向上的动态规划思想解法、线性代数矩阵连乘公式解法
 * @author wly
 * @date 2013-11-28 
 *
 */
public class FibonacciSequence {
	
	private static int TESTCASE = 43;
	
	private static int[][] matrixUnit = {{1,1},{1,0}};
	
	public static void main(String[] args) {
		
		System.out.println("测试规模:" + TESTCASE);
		
		//---朴素递归解斐波那契数列问题测试
		long startT = System.currentTimeMillis();
		System.out.println("朴素递归:" + simpleRecurrence(TESTCASE));
		System.out.println("朴素递归用时:" + (System.currentTimeMillis()-startT));
		
		//---自底向上(动态规划)解斐波那契数列问题测试
		startT = System.currentTimeMillis();
		System.out.println("自底向上(动态规划):" + downToTopReslove(TESTCASE));
		System.out.println("自底向上(动态规划)用时:" + (System.currentTimeMillis()-startT));
	
		//---线性代数矩阵解斐波那契数列问题测试
		int[][] mResult = {{1,1},{1,0}};
		startT = System.currentTimeMillis();
		int n = 1;
		while(n<TESTCASE) {
			mResult = matrixMutiple(mResult, matrixUnit);
			n ++;
		}
		System.out.println("线性代数矩阵公式:" + mResult[0][1]);
		System.out.println("线性代数矩阵公式用时:" + (System.currentTimeMillis()-startT));

		//分治法求m的n连乘测试
		System.out.println("分治法求2的23连乘:" + pow(2, 23));
	
		//两矩阵相乘方法测试
		/*
		int[][] matrix1 = {{2,3,4},{1,2,3}};
		int[][] matrix2 = {{2,4},{3,5},{4,6}};
		int[][] result = new int[matrix1.length][matrix2[0].length];
		int[][] resultS = matrixMutiple(matrix1,matrix2,result);
		System.out.println();
		*/
		
	}
	
	
	/**
	 * 朴素递归
	 * @param n 
	 * @return 第n个斐波那契数
	 */
	public static int simpleRecurrence(int n) {
		if(n == 0) {
			return 0;
		} 
		if(n == 1 || n == 2) {
			return 1;
		}
		
		return simpleRecurrence(n-1) + simpleRecurrence(n-2);
	}
	
	/**
	 * 自底向上包含"动态规划"思想的解法
	 * @param n
	 * @return 第n个斐波那契数
	 */
	public static int downToTopReslove(int n) {
		if(n == 0) {
			return 0;
		} else if(n == 1 || n == 2) {
			return 1;
		} else {
			int[] fibonacciArray = new int[n+1]; //fibonacciArray[i]表示第i个斐波那契数
			fibonacciArray[0] = 0;
			fibonacciArray[1] = 1;
			fibonacciArray[2] = 1;
			for(int i=3;i<=n;i++) { //注意由于fibonacciArray[0]表示第0个元素,这里是i<=n,而不是i<n
				fibonacciArray[i] = fibonacciArray[i-1] + fibonacciArray[i-2];
			}
			
			return fibonacciArray[fibonacciArray.length-1];
		}
	}
	
	
	/**
	 * 分治法求解factor的n次方
	 * @param factor 基数
	 * @param n 次方数
	 * @return
	 */
	public static long pow(long factor,int n) {
		if(n == 0) {
			return 1;
		} else if(n == 1){
			return factor;
		} else {
			if(n % 2 == 1) { //乘法数为奇数
				return pow(factor,(n-1)/2) * pow(factor, (n-1)/2) * factor;
			} else { //乘方数为偶数
				return pow(factor, n/2) * pow(factor, n/2);
			}
		}
	}
	
	/**
	 * 两矩阵相乘
	 * @param matrix1
	 * @param matrix2
	 * @return
	 */	
	public static int[][] matrixMutiple(int[][] matrix1,int[][] matrix2) {
		int[][] result = new int[matrix1.length][matrix2[0].length];
		for(int i=0;i<matrix1.length;i++) {
			for(int j=0;j<matrix2[i].length;j++) {
				int temp = 0;
				for(int k=0;k<matrix1[0].length;k++) {
					temp = matrix1[i][k] * matrix2[k][j] + temp;
				}
				result[i][j] = temp;
			}
		}
		return result;
	}
}
       operation result:
测试规模:43
朴素递归:433494437
朴素递归用时:1669
自底向上(动态规划):433494437
自底向上(动态规划)用时:0
线性代数矩阵公式:433494437
线性代数矩阵公式用时:1
分治法求2的23连乘:8388608

       One thing to be noted here is that the code has been included in the n-th power of m code. It combines had wanted to speak to the third linear algebra, matrix continually multiply in the solution, but later found that case, the code look messy, so they simply use a while to realize even by n times. Overall still achieve three different methods of solution Feibolaqi the number of columns, we hope that we can reference

       O friends ~ ~ ~

       Reproduced leave Source:

       Thank you!!

Reproduced in: https: //my.oschina.net/cjkall/blog/195815

Guess you like

Origin blog.csdn.net/weixin_34293911/article/details/91756559