关闭

从斐波那契数列窥探动态规划

标签: 动态规划分治法
290人阅读 评论(0) 收藏 举报
分类:

利用动态规划求解斐波那契数列

public class Fibonacci 
{
	static int f[]=new int[100];
	static long startTime=0;
	public static void init()
	{
		for(int i=0;i<f.length;i++)
			f[i]=-1;
	}
	public static void main(String[] args)
	{
		init();
		
		startTime=System.currentTimeMillis();
		fibonacci(40);
		System.out.println("time:"+(System.currentTimeMillis()-startTime));
		
		fibonacci2(40);
		
		startTime=System.currentTimeMillis();
		System.out.println(fibonacci3(40));
		System.out.println("time:"+(System.currentTimeMillis()-startTime));
	}
	static int fibonacci(int i) //递归是一种自上而下的动态规划。
	{
		if(i==0)
		{
			return 0;
		}
		else if(i==1)
		{
			return 1;
		}
		else 
		{
			return fibonacci(i-1)+fibonacci(i-2);
		}
	}
	static int fibonacci2(int n) //一般的动态规划,就是这种自下而上的动态规划
	{
		int[] array=new int[n+1];
		array[0]=0;
		array[1]=1;
		long startTime=System.currentTimeMillis();
		for(int i=2;i<n+1;i++){
			array[i]=array[i-1]+array[i-2];
		}
		for(int i=1;i<n+1;i++){
			System.out.print(array[i]+"  ");
		}
		System.out.println();
		System.out.println("time:"+(System.currentTimeMillis()-startTime));
		return array[40];
	}
	static int fibonacci3(int n)  //备忘录法,跟自顶向下的动态规划递归是一样的,不同的是备忘录法利用了一个数组来记录每个子问题的解,从而避免重复求解,将问题简化。
	{
			if(f[n]>=0)
				return f[n];
			if(n == 0)
			{
				f[0] = 0;
				return f[0];
			}
			if(n == 1)
			{
				f[1] = 1;
				return f[1];
			}
			f[n] = fibonacci3(n-1) + fibonacci3(n-2);
			return f[n];
	}
}

结果如下:

time:545
1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181  6765  10946  17711  28657  46368  75025  121393  196418  317811  514229  832040  1346269  2178309  3524578  5702887  9227465  14930352  24157817  39088169  63245986  102334155  
time:0
102334155
time:0

相比较:备忘录法和自下向上的动态规划效率差不多,而自顶向下的递归则效率很慢。是以空间换时间的做法。

动态规划分为三种:自上而下有两种,备忘录法和递归。自下而上有一种,就是一般我们所使用的。

而备忘录和递归不同,备忘录法利用了一个额外数组来存储,计算过程中子问题的解,从而避免了递归方法中重复求解子问题的问题。

除了以上几种方法外还有求通项公式的方法直接得出F(n)=(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}。求解更快速,但这是利用数学的方法,编程时不支持这样做。

结论:

动态规划求解的问题的一般要具有3个性质:

(1) 最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。

(2) 无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。

(3) 有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:65981次
    • 积分:1609
    • 等级:
    • 排名:千里之外
    • 原创:91篇
    • 转载:43篇
    • 译文:0篇
    • 评论:6条
    最新评论