感谢华北电力大学王墨玉老师的ppt
动态规划
基础知识
- 最优化概念:在一定条件下,找到一种途径,使对各阶段的效益,经过按问题具体性质所确定的运算以后,使得全过程的总效益达到最优
- 关键点:对阶段的划分(必须依据题意分析,寻求合理的划分阶段,很重要!很重要!很重要!)
- 多阶段决策过程:在任一阶段后的行为都依赖于该阶段的状态,而与该阶段之前的过程是如何达到这种状态的方式无关。(通俗理解:对一阶段a,a 之后的阶段都依赖于a 阶段,但是与达到a 阶段的方式无关)
- 最优性原理(Principle of Optimality):无论过程的初始状态和初始决策是什么,其余的决策都必须相对于初始决策所产生的状态构成一个最优决策序列。(最优化原理是动态规划的基础,任何问题,如果失去了最优化原理的支持,就无法应用动态规划)
- 解决动态规划问题的基本方法:根据最优化原理导出动态规划基本方程(这个真的很重要,这是提升自己层次的重中之重)
- 最优子结构性质:原问题的最优解包含了其子问题的最优解
- 子问题重叠性质:每次产生的子问题并不总是新问题,有些子问题被反复计算多次
动态规划的适用条件
- 解决一定条件的最优策略问题
- 满足最优子结构性质和子问题重叠性质
动态规划与分治法和贪心法
- 相似点:都是将问题归纳为更小的、相似的子问题,并通过求解子问题产生一个全局的最优解。
- 贪心法在当前阶段的选择可能会依赖之前阶段的选择,但不会依赖之后阶段的选择;贪心法在做选择的同时,将原本的问题不断简化,因此贪心法是自顶向下的;贪心法解决的问题具有最优子结构性质,但是没有子问题重叠性质
- 分治法的各个子问题是独立的,递归的求出各子问题的解后,就可以自下而上的将子问题的解合并成原问题的解
- 如果当前阶段的选择要依赖之后阶段时,就难以通过局部的贪心策略得到全局的最优解
- 如果子问题不独立,则分治法将会重复计算公共的子问题
- 对应上述 3、4 两个问题,动态规划上场了!
- 动态规划可以获得一个最优解(不管原问题有几个最优解,动态规划算法只会取其中一个)
- 动态规划对每个子问题求解后变保存下来,避免了重复计算
动态规划的两种处理方法
- 向前处理法(逆序法): 从最后阶段开始,根据求解方程,逐步向前推导,以求得原问题的最优解。
- 向后处理方法(顺序法):从初始阶段开始,根据求解方程,逐步向后推导,以求得原问题的最优解。
- 选择的原则:
- 一般地说,两种解法在本质上没有什么不同,通常情况下,当初始状态给定时用向前处理解法较方便,当终止状态给定时用向后处理解法较方便。
- 但若初始状态虽已给定,然而终点状态较多,需比较到达不同终点状态的各个路径及指标函数值,以选取总效益最佳的终点状态时,以使用向后处理解法比较方便。
- 另外在初始状态和终止状态均为已知,但当使用不同方法第一步需处理的状态不同时,以选择第一步需处理较多状态的方法为比较合适,这样可以减少运算工作量(可以自行试验他们的工作量)。
- 灵活地选用这两种方法之一,可以使求解过程简化。
基本步骤
- 找出最优解的性质,并刻画其结构特征
- 递归地定义最优解
- 以自底向上(由后向前推)的方式计算最优解
- 根据计算最优解时得到的信息,构造一个最优解(其实说实话,这几句话我也没看懂,,,其实就是根据你选的处理方法,结合要处理问题的性质,定义一个 递归的求解方程 ,然后根据求解方程求得各阶段的最优解,最终获得原问题的最优解。 至于什么是 “递归的求解方程” 看后面的多段图里的求解方程就明白了)
应用实例
多段图问题
- 多段图就是带权值的有向图。
- 这里详细说下向前处理法
- 求解方程:COST (i , j)=min {c (j , r)+COST (i+1,r)}
- COST(i,j),括号中的第一个参数表示阶段,第二个参数表示处于该阶段中的节点号,整体代表从终点到达 j 节点的最短路径
- c(j,r),括号中的第一、二个参数分别是路径的起点和终点,整体的值代表路径的权值
- 第四阶段:
- COST(4,9)=4
- COST(4,10)=2
- COST(4,11)=5
- 第三阶段:
- COST(3,6)=min{6+COST(4,9), 5+COST(4,10)}=7
- COST(3,7)=min{4+COST(4,9), 3+COST(4,10)}=5
- COST(3,8)=min{5+COST(4,10), 6+COST(4,11)}=7
- 第二阶段
- COST(2,2)=min{4+COST(3,6), 2+COST(3,7), 1+COST(3,8)}=7`·
- COST(2,3)=min{2+COST(3,6), 7+COST(3,7)} =9
- COST(2,4)=18
- COST(2,5)=15
- 第一阶段:
- COST(1,1)=min{9+COST(2,2), 7+COST(2,3), 3+COST(2,4), 2+COST(2,5)}=16
- 这样就得到了最终的最优解,16
- 向后处理法,与向前处理法基本一样,就是要注意求解方程变了:BCOST (i , j)=min {BCOST (i-1,r) +c (r , j)}
- 这里有相应的算法和数据结构的描述:https://blog.youkuaiyun.com/ncepuzhuang/article/details/8923790
- 这里有代码 没有验证过:https://blog.youkuaiyun.com/u014359097/article/details/49852475
0/1 背包问题
-
问题描述:
给定n种物品和一个容量为 X 的背包。物品 i 的重量是 Wi,其价值为 pi。假定将物品 i 的放入背包产生 pixi 的效益, 应如何选择装入背包的物品,使得装入背包中物品的总价值最大? -
0/1 背包问题的 x 只能取 0 或 1,也就是说物品只能全部放入或者不放入
-
假定决策x的次序为x1,x2,…,xn,则在对x1作出决策后,问题处于下列两种状态:
X1=0, 背包的剩余容量为M,没有产生任何效益
X1=1, 背包剩余容量为M-w1,效益值增加了p1 -
先选定物品 q,对不同的容量,尝试放入或者不放入物品 x ,取两种情况中的最大值并记录,最终选的是谁不知道,但一定是最大值。对下一个物品重复上述步骤(要结合后面的计算过程去理解)
-
则fn(M) (表示价值)可表示为:fn (M) = max { fn-1(M) , fn-1(M-wn)+pn }(状态方程、求解方程)
*上述字母含义:1)M 为容量 ; 2)n代表第 n 件物品 ; 3)wn 为物品的重量 ; 4)pn 为物品的价值 -
例题:例:n=3, M=6, (w1,w2,w3)=(2,3,4) , (p1,p2,p3)=(1,2,5)
- 设初始值:f0(x>=0)=0;f0(x<0)=-9999(负无穷)
- f1(1)= max{ f0(1),f0(1-w1)+p1}=0
f1(2)= max{ f0(2),f0(2-w1)+p1}=p1=1
此时:f1(3)= f1(4)= f1(5)= f1(6)=1 - f2(1)= max{ f1(1),f1(1-w2)+p2}=0
f2(2)= max{ f1(2),f1(2-w2)+p2}=1
f2(3)=f2(4)= max{ f1(3),f1(3-w2)+p2}=2
f2(5)=f2(6)= max{ f1(5),f1(5-w2)+p2}=3 - f3(M) = f3(6)= max{ f2(6), f2(6-w3)+p3}
= max{3,f1(2)+5}=6
资源分配问题
-
问题描述:
设资源总数为a,工程的个数为 n,给每项工程分配的资源数额不同,所获得的利润也不同。在给定各工程的资源利润表和资源总数,怎样分配资源,才能获得最大利润呢 -
这题分两类
- 第一类:利润和被分配的资源呈线性关系。那这题就没意思了。。。
- 第二类:利润和被分配的资源不程序关系。我们要看的就是这个
-
乍一看,其实和 0/1 背包有点像,如果把题中的产品看作要放入背包的物品,投资额看作背包容量,那么不同之处在于,这个“物品”具有不同的重量,还对应不同的收益。因此不能直接应用 0/1背包的求解方程
-
思路:Gi(x)是把资源数 x 分配给第 i 项工程的最大利润,fi(x)表示对前 i 项投资 x 时获得的最大利润,a 为最大的投资额
-
例题:有资金6万元,拟投资A、B和C三种产品,利润函数G(x)的值给定如下表。求最佳投资方案。
-
这里只对 f1(x) 做个求解
- f1(0) = 0
- f1(1) = 1.2
- f1(2) = 1.5
- f1(3) = 1.85
- f1(4) = 2.4
- f1(5) = 2.8
- f1(6) = 3.3
- 后面的,类似于:f2(3) = max{G2(0)+f1(3-0),G2(1)+f1(3-1),G2(2)+f1(3-2),G2(3)+f1(3-3)} = max{1.85,3.3,3.2,2.25} = 3.3
- 最终答案是 4.6 有兴趣可以试试
货郎担问题
-
问题描述:
某售货员要到若干个村庄售货,各村庄之间的路程是己知的,为了提高效率,售货员决定从所在商店出发,到每个村庄售一次货然后返回商店,问他应选择一条什么路线才能使所走的总路程最短? -
货郎担问题和多段图问题很像,不同之处在于,货郎担问题求的是周游路线的最短路径(最小成本的周游路线)。周游路线:顾名思义,从起点出发,经过所有节点之后还要再回到起点。
-
最优性原理证明:
-
例题:求从节点 1 出发再回到 1 的最短周游路线
-
思路:求经过 0 个节点回到 1 的最短路径,经过 1 个节点回到 1,经过 2 个节点回到 1……
- 这样就问题就是一个多阶段决策过程了
-
求解方程:g (i, S)= min { c (i,j) + g (j, S-{j})}, j∈S
- g(2,Ø)=c(2,1)=5 ,
g(3,Ø)=c(3,1)=6 ,
g(4,Ø)=c(4,1)=8 - g(2,{3})=c(2,3) + g(3,Ø)
= 9+6 =15
(结点2经过结点3到结点1的路线长度)
g(2,{4})=c(2,4) + g(4,Ø) = 10+8 =18
g(3,{2})=c(3,2) + g(2,Ø) = 6+5 =11
g(3,{4})=c(3,4) + g(4,Ø) = 12+8 =20
g(4,{2})=c(4,2) + g(2,Ø) = 8+5 =13
g(4,{3})=c(4,3) + g(3,Ø) = 9+6 =15 - g(2,{3,4})
= min{c(2,3) + g(3,{4}),
c(2,4)+ g(4,{3}) }
= min{9+20,10+15} = 25
(结点2经过结点3、4到结点1的路线长度)
g(3,{2,4})
=min{c(3,2) + g(2,{4}),
c(3,4)+ g(4,{2}) }
=min{6+18,12+13} = 24
g(4,{2,3})
=min{c(4,2) + g(2,{3}), c(4,3)+ g(3,{2}) }
=min{8+15,9+11} = 20 - 最后:
g(1,{2,3,4})
= min{c(1,2) + g(2,{3,4}), c(1,3) + g(3,{2,4}),
c(1,4)+ g(4,{2,3}) }
= min{10+25 , 15+24 , 20+20}
= 35
(结点1经过
结点2、3、4
最后到达结点1的最短路径)
- g(2,Ø)=c(2,1)=5 ,
-
时间复杂度:
- 枚举法很明显是 O(n-1)!
- 动态规划的是 O(n22n),比枚举法有所改进