zoukankan      html  css  js  c++  java
  • 算法之递归、分治策略、动态规划以及贪心算法之间的关系

    https://blog.csdn.net/tyhj_sf/article/details/53969072

    转载:http://blog.csdn.net/tyhj_sf/article/details/53969072

    引言

    最近集中研究计算智能,其中涉及到递归和动态规划,动态规划实现中又用到了递归,忽然发现这两个概念的差别分得不太清楚。索性把递归、分治策略、动态规划、贪婪选择之间的联系与区别都一并搞清楚吧。

    1、分治策略(Divide and Conquer)

    将原问题分解为若干个规模较小但类似于原问题的子问题(Divide),递归的求解这些子问题(Conquer),然后再合并这些子问题的解来建立原问题的解。因为在求解大问题时,需要递归的求小问题,因此一般用递归的方法实现,即自顶向下。

    2、动态规划(Dynamic Programming)

    动态规划其实和分治策略是类似的,也是将一个原问题分解为若干个规模较小的子问题,递归的求解这些子问题,然后合并子问题的解得到原问题的解。区别在于这些子问题会有重叠,一个子问题在求解后,可能会再次求解,于是我们想到将这些子问题的解存储起来,当下次再次求解这个子问题时,直接拿过来就是。其实就是说,动态规划所解决的问题是分治策略所解决问题的一个子集,只是这个子集更适合用动态规划来解决从而得到更小的运行时间。即用动态规划能解决的问题分治策略肯定能解决,只是运行时间长了。因此,分治策略一般用来解决子问题相互对立的问题,称为标准分治,而动态规划用来解决子问题重叠的问题。

    动态规划一般由两种方法来实现,一种为自顶向下的备忘录方式,用递归实现,一种为自底向上的方式,用迭代实现。

    3、贪心算法(Greedy Algorithm)

    贪心算法在每一步都做出最优的选择,希望这样的选择能导致全局最优解。对,只是寄希望,因此贪心算法并不保证得到最优解,但是它对很多问题确实可以得到最优解,而且运行时间更短。由此可见,贪心算法是带有启发性质的算法。那什么时候可以用贪心算法呢?当该问题具有贪心选择性质的时候,我们就可以用贪心算法来解决该问题。 
    贪心选择性质:我们可以通过做出局部最优(贪心)来构造全局最优。只要我们能够证明该问题具有贪心选择性质,就可以用贪心算法对其求解。比如对于0-1背包问题,我们用贪心算法可能得不到最优解(当然,也可能会得到最优解),但对于部分背包问题,则可以得到最优解,贪心算法可以作为0-1背包问题的一个近似算法。

    动态规划与递归的比较

    就性能而言,我用递归和动态规划实现了斐波纳契数列计算,递归如果超过40的时候就已经需要很长时间了,40次大概需要1秒左右,但是用动态规划要一亿次,才需要4秒,这个相差的可不是几个数量级的问题。事实上,递归实现的斐波那契数列计算时间复杂度为O(2ⁿ),动态规划实现时间复杂度为O(n)所以,在以后的开发中,尽量避免使用递归。 
    就具体实现上而言,动态规划比普通递归仅仅是多了一步保存子问题计算结果的操作。 
    例如,斐波那契数列的递归实现如下:

     int F(int i)
        {
                 if(i < 1)  return 0;
                 if(i == 1) return 1;
                  return F(i-1) + F(i - 2);
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    而用动态规划算法实现是这样:

     int F(int i)
    {
         if(knownF[i] != unknown){
            return knownF[i];
         }
         if(i == 0) t = 0;
         if(i == 1) t = 1;
         if(i > 1)  t = F(i - 1) + F(i - 2);
         return knownF[i] = t;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、总结

    1. 分治策略用于解决原问题与子问题结构相似的问题,对于各子问题相互独立的情况,一般用递归实现;
    2. 动态规划用于解决子问题有重复求解的情况,既可以用递归实现,也可以用迭代实现;
    3. 贪心算法用于解决具有贪心选择性质的一类问题,既可以用递归实现,也可以用迭代实现,因为很多递归贪心算法都是尾递归,很容易改成迭代贪心算法;
    4. 递归是实现手段,分治策略是解决问题的思想,动态规划很多时候会使用记录子问题运算结果的递归实现。

    参考资料: 
    1.http://1661518.blog.51cto.com/1651518/1396943 
    2.《算法导论》第三版

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tyhj_sf/article/details/53969072
  • 相关阅读:
    struts2下,jsp视图页面中CSS和javascript引用相对路径和绝对路径问题。
    浏览器和web开发中的编码问题
    一台电脑同时配置2个tomcat
    hibernate中“deleted object would be re-saved by cascade”异常原理和解决方案
    hibernate Unknown entity异常解决方案
    rose2003安装后,启动时提示 计算机缺少suite objects.dll解决方案
    Eclipse下构建hibernate项目流程
    Hibernate不能自动建表解决办法【转载】
    Eclipse安装hibernate插件的问题
    MyEclipse添加tomcat7出现“Value must be an existing directory”解决方案
  • 原文地址:https://www.cnblogs.com/tianzijiaozi/p/9114519.html
Copyright © 2011-2022 走看看