目录
一、动态规划的思想方法
1、动态规划的最优决策原理
二、动态规划的特征
三、动态规划算法步骤
四、动态规划实例
实例1、0-1背包问题
实例2、货郎担问题
实例3、多段图最短路径问题
实例4、资源分配问题
动态规划(Dynamic Programming,DP)方法对问题进行全面的规划处理,从而弥补了贪婪法在这方面的不足。下面叙述动态规划的最优决策原理,并以货郎担问题为例说明动态规划的思想方法。
对于具有n个输入的最优解问题,他们的活动过程往往划分为若干个阶段,每一阶段的决策依赖于前一阶段的状态,由决策所采取的动作使状态发生转移,成为下一阶段的决策依据。
20世纪50年代,贝尔曼等人根据这类问题的多阶段决策
特性,提出了解决这类问题的最优性原理。这个原理指出:无论过程的初始状态和初始决策是什么,其余的决策都必须相对于初始决策所产生的状态,构成一个最优决策序列。
由于每一阶段的决策,仅与前一阶段所产生的状态有关,而与如何达到这种状态的方式无关。因此,可以把每一阶段作为一个子问题来处理。
在决策过程中,有一个赖以决策的策略或目标,把这种策略或目标称为动态规划函数。它由问题的性质和特点所确定,并应用于每一阶段的决策。因此,整个决策过程可以递归进行,或用循环迭代的方法进行。这样,动态规划函数可以递归地定义,也可以用递推公式来表达。
1、最优子结构
①组合优化问题,指的是问题有多个可行解,每一个可行对应一个目标值,目的是要在可行解中求得目标值最优者(最大或最小)。
②最优子结构特性,指的是问题的最优解包含的子问题的解相对于子问题而言也是最优的。
2、子问题重叠
①问题的一个递归算法在每个递归步骤产生分支子问题时不总是最新的,而是对部分子问题解了又解。
②当一个递归算法一次又一次地访问同一个子问题时,我们说该最优化问题具有重叠特性。
一般分成三个阶段
(1)分段:将原问题分解为若干个互相重叠的子问题;
(2)分析:分析问题是否满足最优性原理,找出动态规划函数的递推式;
(3)求解:利用递推式自底向上计算,从子问题的最优解逐步构造出整个问题的最优解,实现动态规划过程。
设 m[i][j] 是子问题W={w1,w2,...,wi},V={v1,v2,...,vi},数值 j 的最优解的目标值,其中,i=1,2,...,n,j=1,2,...,M。根据最优子结构特性,有递推公式:
算法的时间复杂度是:
(n是物体数量,m是背包容量)
例:有五个物品,其重量分别是{2,2,6,5,4},价值分别为{6,3,5,4,6},背包的容量为10。
解:
用一个(n+1)×(m+1)的二维表dp[ ][ ],m[ i ][ j ]表示把前 i 个物品装入容量为 j 的背包中获得的最大价值,根据递推公式将dp表填写如下。
容量 序号 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
(w,v) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
(2,6) | 1 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
(2,3) | 2 | 0 | 0 | 6 | 6 | 9 | 9 | 9 | 9 | 9 | 9 | 9 |
(6,5) | 3 | 0 | 0 | 6 | 6 | 9 | 9 | 9 | 9 | 11 | 11 | 14 |
(5,4) | 4 | 0 | 0 | 6 | 6 | 9 | 9 | 9 | 10 | 11 | 13 | 14 |
(4,6) | 5 | 0 | 0 | 6 | 6 | 9 | 9 | 12 | 12 | 15 | 15 | 15 |
从图中可以看到,装入背包的物品的最大价值为15,装入背包的物体为x={1,1,0,0,1}。
如果对任意数目的n个城市,分别用1~n的数字编号,则这个问题归结为在赋权图G=
V={1,2,...,n} 表示城市顶点,
边(i,j)∈E 表示城市 i 到城市 j 的距离,i,j=1,2,3,...,n。
这样,可以用图的邻接矩阵C来表示各个城市之间的距离,把这个矩阵称为费用矩阵,如果
(i,j)∈E, >0,否则 =∞ 。
令d(i,)表示从顶点 i 出发,经中各个顶点一次,最终回到初始出发点的最短路径的长度。开始时, = - { i }。于是,可以定义下面的动态规划函数:
下面用4个城市的例子,来说明动态规划方法解货郎担问题的工作过程。假定4个城市的费用矩阵是: