分治、动态规划、贪婪 之 算法分析

分治、动态规划、贪婪  之 算法分析

分治动态规划都用到了递归的思想,但是对他们之间的区别在概念上一直比较模糊,今天附带贪婪选择稍微整理一下他们。


算法之道上说,标准分治、动态规划、贪婪选择称得上是孙子兵法的下、中、上策。标准分治虽然将大问题分解成小问题,但是每个小问题都需要解决,相当于逢城必攻实属下策动态规划则聪明地发现,很多子问题都相同,那么重复的子问题可以不用重复计算,就是不对每个城市进行攻破,从而节省精力和兵力,但仍然需要攻克子问题中的相当部分,属于中策;而贪婪选择则将子问题限于一个,即将攻城数量减少到了最低,从而最大限度上减少了精力和兵力,属于上策。不过就像兵法里所云,上策运用地不好,就有失策的时候。贪婪思想运用地不当,或者在条件不充分或不明朗的条件下用,则会大败而归。


从另一个方面看,三种策略都为了在求解问题的时候成本尽量低,因此,从这个方面看,三种策略的目标一致,但是标准分治策略的目标只是获得问题的解动态规划贪婪选择不仅是要获得一个解,而且应该是个最优解,因此贪婪选择和动态规划之间的相似性最多。不过虽然动态规划和贪婪选择策略有许多相同的地方,但是有时候并不容易看出来。贪婪选择属性指的是一个全局最优解决方案可以通过解决一个局部最优的选择来获得。对于一个贪婪算法来说,其选择具有贪婪的性质,那么对于动态规划来说呢,他每一步都需要作出一个选择,而是在已知子问题解的基础上作出的当前最好的选择,所以动态规划每一步都需要运用贪心策略。也就是说,贪婪策略是在解决子问题前作出选择,希望作出的选择是正确的,是自顶向下动态规划则是在求解子问题后作出选择,是自底向上但不管是在之前还是之后做选择,都是试图作出最好的选择。背包问题可用贪心策略来解决。


分治法和递归是紧密联系的,分治就是把大问题分解成规模较小的子问题,然后大问题的解可以通过小问题的解得出来,小问题是相互独立的,可以通过递归来解决。
分治法所能解决的问题一般具有以下几个特征:
该问题的规模缩小到一定程度可以很容易地解决;
该问题可以分解成若干规模相同的子问题,即该问题具有最优子结构性质;
利用该问题分解出的子问题的解可以合并成该问题的解;
该问题所分解出的子问题是相互独立的,即子问题不包含公共的子问题。
分治在每一层递归上都要完成分解、解决、合并三个操作。

归并排序、堆排序、快速排序都有分治算法的思想。


通常遇到的复杂问题不能简单地分解成几个子问题,而是会分解成一系列子问题并且子问题并不是相互独立的,简单地把大问题分解成子问题,并综合子问题的解求出大问题的解的方法,问题求解时会按问题规模呈现幂级数增加。为了节约重复求相同子问题的时间,引入一个数组,不管他们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。典型的Fibonacci数列的求解就运用了动态规划的思想。

posted @ 2014-05-11 10:08  Never say Ever  阅读(755)  评论(0编辑  收藏  举报