首页 > 代码库 > 动态规划算法

动态规划算法

  R.Bellman等人于1951年在研究多阶段决策过程优化问题时所创立的一种用于解决此类过程优化问题的新方法。

逆向递归的方法称为动态规划法(Dynamic Programming).

 

多阶段决策

  有一类问题可以将其活动过程分解成若干个相互联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。在每个阶段所作出的决策选择依赖于当前状态,又影响以后的发展。当各阶段决策确定后,就组成一个决策序列,从而就确定了整个过程的一条活动路线。这种将一个问题看作是一个前后相互关联且具有链状结构的多阶段过程称为多阶段决策。 

  通常情况下,在多阶段决策过程中,某一阶段会存在多个决策序列,如果在进行决策时遵循如下原则:求解过程为自底向上(即从终点到起点),每一步的选择总是依赖于上一步的选择,且此步仅把不可能的决策序列排除在外。

  动态规划注意适用于最优化问题的求解。这类问题可能有多个可能的解,每个解都有一个值,而动态规划就是找出其中最优(最大或最小)值的解。若存在若干个最优值的解,只取其中的一个。

  

 

  动态规划与分治法、贪心法类似,都是将原问题分解为若干个更小的、相似的子问题,并通过求解子问题产生一个全局最优解。其不同之处如下:

(1)使用贪心法时,当前选择可能要依赖于已经作出的所有选择,但不依赖于有待于作出的选择和子问题。因此贪心法是自顶向下(即从起点到终点),一步一步地作出贪心选择。当然,如果当前的选择可能要依赖于子问题的解时,则难以通过局部的贪心策略达到全局最优解。

(2)使用分治法时,由原问题分解出的各个子问题通常是相互独立的,即不包含公共的子问题,因此一旦递归地求出各子问题的解后,便可自下而上地将各子问题的解合并成问题的解。如果各个子问题不是相互独立的,则分治法要做出许多不必要的工作,重复求解公共的子问题。

(3)动态规划允许由原问题分解出的子问题之间相互依赖。每个子问题只求解一次,并将结果保存起来,避免每次碰到此问题时都要重复计算。

综上所述,动态规划的基本思想是将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后再从这些子问题的解得到原问题的解。对于重复出现的子问题,只在第一次遇到时对它进行求解,并把中间计算结果保存起来,以后再次遇到时直接引用中间计算结果,不必重新求解。

 

动态规划适用条件

(1)最优化原理(最优子结构性质)

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

  所谓最优化原理是指无论前面的策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。由于对于有些问题的某些递归式来讲并不一定能保证最优原则,因此在求解问题时有必要对它进行验证。若不能保持最优原则,则不可以应用动态规划方法求解。在得到最优解的递归式后,需要执行回溯以构造最优解。

(2)无后效性

  应用动态规划的一个重要条件就是将各阶段按照一定的次序排列好,阶段i的状态只能由阶段i+1的状态来确定,与其他状态没有关系,尤其是与未发生的状态没有关系。每个状态都是“过去历史的一个完整总结”。

(3)子问题的重叠性

  子问题的重叠性是指利用递归算法自顶向下对问题求解时,每次产生的子问题并不总是新问题,有些子问题可能被重复计算多次。动态规划法正是利用子问题的这种重叠性质,对每一个子问题只计算一次,然后将其计算结果保存起来,当再次需要计算已经计算过的子问题时,只是简单查看一下以往计算结果,从而获得高的解题效率。

  子问题的重叠性并不是动态规划的必要条件,如果不满足该条件,动态规划与其他算法相比就无优势。

 

 

动态规划法解决问题的步骤

(1)分析:对原始问题进行分析,找出问题的最优解的结构特征。

(2)分解:将所给问题按时间或空间特性分解成若干相互关联的阶段,并确定出计算局部最优解的递推关系,这是利用动态规划法解决问题的关键和难点所在。需要注意,分解后的各个阶段一定是有序的或者是可排序的,即无后向性。否则问题就无法用动态规则求解。

(3)解决:对于每个阶段通过自底向上方法求得局部问题的最优解。需要一个递推的终止条件或边界条件。

(4)合并:将各个阶段求出的解合并为原问题的解,即构造一个最优解。

 

  整个求解过程可以使用一个最优决策表的二维数组来描述,其中行表示决策的阶段,列表示问题状态,表格需要填写的数据一般对应此问题在某个阶段式某个状态下的最优值,如最短路径、最长公共子序列、最大价值等。填表过程就是根据递推关系从1行1列开始,以行或者列优先的顺序,依次填写表格。最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。

  动态规划关键在于解决冗余,是一个以空间换时间的技术,所以它的空间复杂度要大于其他的算法。

 

 

动态规划法应用举例:

多源最短路径

  对于一个给定的非负有向网图,求出任意两个节点之间的最短路径。通常有两种方法,一个是分别以图中每个顶点为源点共调用n次Dijkstra算法;其二是采用Floyed算法。两种方法时间复杂度都是O(n*n*n),后者比较简单。

 

http://blog.csdn.net/wangdd_199326/article/details/62235750

 

动态规划算法