1. 程式人生 > >動態規劃解——有向圖中的最長路徑

動態規劃解——有向圖中的最長路徑

動態規劃博大精深,想完全掌握是很難的,不過我們可以從一些簡單的例子之中去體會她的奧妙。

不說廢話、先來一個簡單的例子吧:

longest path in DAG

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.

第一次覺得要講清楚一件事還挺不容易的O(∩_∩)O~大半個晚上才搞定得。。。汗!

有不得當的地方希望高手指正呀!

相關推薦

動態規劃——路徑

動態規劃博大精深,想完全掌握是很難的,不過我們可以從一些簡單的例子之中去體會她的奧妙。 不說廢話、先來一個簡單的例子吧: longest path in DAG Problem: Given a weighted directed acyclic graph  G=(V,

路徑及是否存在環路結構

問題描述: 有n個長為m+1的字串,如果某個字串的最後m個字元與某個字串的前m個字元匹配,則兩個字串可以連線。問這n個字串最多可以連成一個多長的字串,如果出現迴圈,則返回錯誤。 分析: 把每個字串看成一個圖的頂點,兩個字串可以連線就形成一條有向邊。相當於判斷一個有向圖是否存

實驗七 采用Dijkstra算法求帶權路徑

圖解 初始 -s 由於 mic spa 初始化 mil dijkstra Dijkstra算法圖解 說明:初始化:S = { 0 }, U = { 1, 2, 3, 4, 5, 6 }, dist[ ] = { 0, 4, 6, 6, ∞, &in

[CareerCup] 4.2 Route between Two Nodes in Directed Graph 兩點的路徑

4.2 Given a directed graph, design an algorithm to find out whether there is a route between two nodes. LeetCode和CareerCup中關於圖的題都不是很多,LeetCode中只有三道,分別

路徑

 阿里巴巴的一個程式設計測驗 輸入: 5 4 3 2 10 5 7 1 2 1 3 2 5 4 5 輸出:  3 13   #include <iostream> #include <algorithm> using n

路徑演算法

最短路徑演算法屬於資料結構的圖的應用知識。先介紹基本的圖的概念。 圖由頂點集和邊集組成。(一張圖裡不就是有頂點和邊)。圖中邊帶有方向就是有向圖,否則就是無向圖。圖的儲存結構分為鄰接表和鄰接矩陣。(鄰接表主要採用順序儲存和鏈式儲存結合的方式)。採用連結表這種都是對於稀疏圖而言

資料結構——帶權路徑演算法Dijkstra演算法)

Dijkstra演算法是由荷蘭電腦科學家艾茲格·迪科斯徹發現的。演算法解決的是有向圖中最短路徑問題。 舉例來說,如果圖中的頂點表示城市,而邊上的權重表示著城市間開車行經的距離。 Dijkstra演算法可以用來找到兩個城市之間的最短路徑。 Dijkstra演算法的輸入包含了一個有權重的有向圖G,以及G中的一個

【資料結構與演算法】 路徑實現

Goal: Practice the algorithms of shortest pathproblem. Task:用一個有向圖表示給定的n個(要求至少10個)城市(或校園中的一些地點)及其之間的道路、距離情況,道路是有方向的。要求完成功能:根據使用者輸入的任意兩個城

路徑(Floyd演算法)

最近在研究最短路徑演算法,使用java實現。 原始資料是一共有6個點,他們之中任意2個點(i,j)之間的距離v(i,j)的數值如下面二位陣列中所示,整體演算法使用Java語言實現。 class Floyd{ public static void main(S

每日一省之————加權路徑問題

1 加權有向圖中邊的資料結構 /** * 該類用於表示有向圖中的一條有向邊 * @author lhever 2017年3月2日 下午11:25:30 * @version v1.0 */ public class DirectedEdge {

迪傑斯特拉演算法處理無路徑的(dijkstra)Java實現(指定兩點,求短距離及路徑)

其實不是原創哈,我寫不出來。       如何求圖中V0到V5的最短路徑呢?         java實現的方式如下:         第一步,根據圖來建立權值矩陣:        int[][] W = {      {  0,   1,   4,  -1,  -

小環問題

details tarjan csdn class article AI 最小環 問題 cnblogs tarjan https://blog.csdn.net/weixin_39872717/article/details/78472910 http://www.cnbl

12.帶權任意兩點間的路徑

其實它的程式碼理解起來真的挺難的我覺得!!! 昨天看了一下午感覺晦澀難懂,還是matlab好用,直接呼叫函式就可以了!!! 不過這裡還是得跟大家介紹一下: 1.問題的理解: 像這種帶權的有向圖,每一行都表示該行標號對應列標號的有向權值,本身到本身的數值為0,沒辦法

Tree Operations 打印出的環

png 打印 main lis lac system img not follow 題目: You are given a binary tree with unique integer values on each node. However, the child p

LeetCode 210. Course Schedule II(拓撲排序-求是否存在環)

target inpu begin urn take before amp 存在 fin 和LeetCode 207. Course Schedule(拓撲排序-求有向圖中是否存在環)類似。 註意到。在for (auto p: prerequistites)中特判了

查找所有的環

while rem hashset AR i++ nta str for graph 在對每個結點進行DFS的基礎上進行了一些優化。 優化原理:若findCycle(0,e), 找到一個0-2-3的環,那麽不再對2、3進行findCycle()函數。因為2或3若是構成有其它

[] 7.30 求所有簡單迴路-鄰接表-DFS

題目來源:嚴蔚敏《資料結構》C語言版本習題冊 7.30 【題目】試寫一個求有向圖G中所有簡單迴路的演算法 【測試資料】123456對應ABCDEF 【結果】 【答案】 /*-----------------------------------------

C 試基於的深度優先搜尋策略寫一演算法 判別以鄰接表方式儲存的是否存在由頂點 vi到頂點 vj的路徑 i≠j 。

嚴蔚敏 資料結構 7.22 給大佬跪了,這個是要返回的,但是還要兼顧頂點上連線的其他節點,不能一個不行就不行,所以走的路徑只返回走通的,走不通的略過,直到最後,能走到最後就說明根本沒有通的路徑,就這樣。 也可以把這個點上的所有連線點用深度遍歷走一次,然後看看記錄

uva 11183 小生成樹

AC程式碼 #include<bits/stdc++.h> using namespace std; #define N 1300 int pre[N]; int in[N]; int id[N]; int v[N]; struct edge{

小樹形圖【小生成樹】

  做了POJ的一道題,總是WA,不知道為什麼,後來去看了,才知道,原來有向圖的最小生成樹與無向圖不一樣,它得是從某個點出發能遍歷到其他所有點的才行,以此為條件,我們學習到了最小樹形圖。   與很多其他人的講解不一樣吧,我把我看了部落格後自己的思路分享出來,關於什麼是最小