轉自: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.