动态规划解——有向图中的最长路径[转]
转自:http://www.cnblogs.com/yanlingyin/archive/2011/11/12/2246716.html
longest path in DAG(directed acyclic graph)
Problem:
Given a weighted directed acyclic graph G=(V, E), an vertex v, where each edge is assigned an integer weight, find a longest path in graph G
问题描述:
给一个带权有向无环图G=(V,E),找出这个图里的最长路径。
说实话初学者直接给出这个图会看蒙的、再看看问题,不知道从何下手。
好了,对上图做个简单的处理:
现在看起来是不是清晰多了呢
用dilg(v)表示 以点结尾的最长路径,现在考虑dilg(D), dilg(B), dilg(C)
dilg(D)=max{dilg(B)+1, dilg(C)+3}
来解释一下:点D的入度边有CD、BD。
以D结尾的最短路径必定经过C、D中的最后一点;如果是C点,则以dilg(C)+3(权值)定会大于等于dilg(D)+2(权值)
如果没能看懂,请注意dilg(V)的定义
对于任意的点V可以有如下表达式:
dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)}
这样、问题dilg(V)就会被转化为较小的子问题dilg(U)(当然,U是连入V的点)
任何一个问题都可以用这样的方式转化、变小。
但总不能无限变小啊,最后回成为最简单的问题。当有两个点,且其中的一个点入度为0的时候如图中的S-->C他们的最长距离就是
权值2。入门篇中说过,思考方向是从复杂到简单,而计算方向是从简单到复杂。
算法如下
Initialize all dilg(.) values to ∞;
1.Let S be the set of vertices with indegree=0; ////设集合S,里面的是入度为0的点
2.For each vertex v in S do
dilg(v)=0;
3. For each v∈V\S in Topological Sorting order do //对于V中除S外的点、按照拓扑排序的顺序,依次求出最长路径并保存好
dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)} //拓扑排序可以简单的理解为从起点到终点的最短路径
4. Return the dilg(.) with maximum value.
现在是找到最长路径的大小了、但是如何得到最长路径呢?
只需做点小小的改动:
Dplongestpath(G)
Initialize all dilg(.) values to ∞;
Let S be the set of vertices with indegree=0;
for each vertex v in S do
dist(v)=0;
4. For each v∈V\S in Topological Sorting order do
dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)}
let (u,v) be the edge to get the maximum
value;
dad(v)=u;
5. Return the dilg(.) with maximum value.
每一步都记下V的父节点、最后根据dad()数组即可得到路径。
对于上面的问题:先找出子问题、然后解决由子问题如何得到父问题以及如何把子问题分为更小的子问题
注意:问题的本质没有改变,只是规模变小。
我的理解:
动态规划的目的正是在不改变问题本质的情况下不断缩小子问题的规模、规模很小的时候,也就能很容易得到解啦(正如上面的只有两个点的情况)
上图可以这样理解:
问题A5被分成了子问题A3、A4解决它们就能解决A5,由于A3、A4和A5有相同的结构(问题的本质没变)所以A3可以分为问题A1、A2。当然A4也能
分为两个子问题,只是图中没画出来。
下面的是再网上看到的不错的思路:
Dynamic programming:
(1)problem is solved by identifying a collection of
subproblems,
(2) tackling them one by one, smallest rst,
(3) using the answers of small problems to help
figure out larger ones,
(4) until the whole lot of them is solved.