当前位置:   article > 正文

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

菲波拉契数列

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

  1. public class Fibonacci
  2. {
  3. static int f[]=new int[100];
  4. static long startTime=0;
  5. public static void init()
  6. {
  7. for(int i=0;i<f.length;i++)
  8. f[i]=-1;
  9. }
  10. public static void main(String[] args)
  11. {
  12. init();
  13. startTime=System.currentTimeMillis();
  14. fibonacci(40);
  15. System.out.println("time:"+(System.currentTimeMillis()-startTime));
  16. fibonacci2(40);
  17. startTime=System.currentTimeMillis();
  18. System.out.println(fibonacci3(40));
  19. System.out.println("time:"+(System.currentTimeMillis()-startTime));
  20. }
  21. static int fibonacci(int i) //递归是一种自上而下的动态规划。
  22. {
  23. if(i==0)
  24. {
  25. return 0;
  26. }
  27. else if(i==1)
  28. {
  29. return 1;
  30. }
  31. else
  32. {
  33. return fibonacci(i-1)+fibonacci(i-2);
  34. }
  35. }
  36. static int fibonacci2(int n) //一般的动态规划,就是这种自下而上的动态规划
  37. {
  38. int[] array=new int[n+1];
  39. array[0]=0;
  40. array[1]=1;
  41. long startTime=System.currentTimeMillis();
  42. for(int i=2;i<n+1;i++){
  43. array[i]=array[i-1]+array[i-2];
  44. }
  45. for(int i=1;i<n+1;i++){
  46. System.out.print(array[i]+" ");
  47. }
  48. System.out.println();
  49. System.out.println("time:"+(System.currentTimeMillis()-startTime));
  50. return array[40];
  51. }
  52. static int fibonacci3(int n) //备忘录法,跟自顶向下的动态规划递归是一样的,不同的是备忘录法利用了一个数组来记录每个子问题的解,从而避免重复求解,将问题简化。
  53. {
  54. if(f[n]>=0)
  55. return f[n];
  56. if(n == 0)
  57. {
  58. f[0] = 0;
  59. return f[0];
  60. }
  61. if(n == 1)
  62. {
  63. f[1] = 1;
  64. return f[1];
  65. }
  66. f[n] = fibonacci3(n-1) + fibonacci3(n-2);
  67. return f[n];
  68. }
  69. }

结果如下:

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



声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号