Graph圖總結


將COMP20003中關於Graph的內容進行總結,內容來自COMP20003,中文術語並不准確,以英文為准。


 Graph G = {V, E}

  頂Vertices V: can contain information

  邊Edges E (links between vertices): can have direction and/or weight   

種類:

  •   有向圖(directed graph):邊(edge)有方向。
    • 弱有向連接圖Weakly connected directed graph:將有向的邊替換成無向的邊后能得到無向連通圖。

    

    • 強有向連接圖Strongly connected directed graph:在有向圖中,任意頂通過邊到達任意頂。

    

      • Strongly connected components in a directed graph:在同一區域(component)的頂可以到達所有同一區域的頂。

        

  •   無向圖(undirected graph):邊(edge)沒有方向。
    • 無向連通圖Connected Undirected graph: 任意的頂均可通過邊連接到其他頂,包括間接。

    

    •  無向非連通圖Unconnected Undirected graph:即不是無向連通圖Connected Undirected graph。

    

 完全圖Complete graph:每個直接到其他頂。對於無向圖至少需要V(V-1)/2個頂,有向圖至少需要V(V - 1)個頂。


用數據結構表示:

二維數組(Matrix)表示:

注意:未連接用無窮大表示,而不是用0表示。

復雜度O(V2)

鏈表表示:

 

 復雜度O(V + E) 


 圖的遍歷Traversal 

Depth-first search(DFS)深度優先搜索,使用stack實現,基於stack先進后出的特性。

Breadth first search(BFS)廣度優先搜索,使用queue實現,基於queue先進先出的特性。


圖的拓撲:應用於有向無環圖(Directed Acyclic Graphs,簡稱DAG

  Topological sort: a partial ordering that fulfils certain constraints. All edges e(i, j) go in horizontal i -> j direction

                            變成水平排列,只能從左邊指向右邊。

  

  拓撲涉及的概念:

    indegree:該頂被邊到達的次數。

    outdegree:由該頂開始邊連接的次數。

  能有拓撲結構,DAG圖必須滿足有一個source(indegree為0)和sink(outdegree為0)。

  如果在DAG圖中存在漢密爾頓路徑(Hamiltonian path,即從某個頂開始通過邊不重復的經過所有點的路徑,想想游戲一筆畫),則該拓撲是唯一的。

  代碼:https://github.com/Will-Zhu-27/Algorithms-and-Data-Structures/tree/master/graph/Topological%20sort

 


算法:

Dijkstra's algorithm for single source shortest path

Dijkstra單源最短路徑算法:一個頂到其他頂的最短路徑。

基於Greedy algorithm: 最短路徑中的子路徑也是最短路徑,即A到Y的最短路徑經過X,那么該路徑中從A到X的部分是A到X的最短路徑。

假定沒有負值的邊。

使用優先隊列priority queue

步驟:

  使用變量數組dist記錄從目標定到該頂的最短距離,數組pred記錄經過該頂的前一個頂,edgeWeight(a, b):頂a到頂b邊的值。

    1. 將dist自己到自己為0,其余最大(MAX_INT)。pred均為NULL。
    2. 將所有頂裝入優先隊列,按照對應的dist值的大小為優先度。
    3. 當優先隊列不為空時,pop一個頂a,為空則結束。
    4. LOOP:如果dist[a] + edgeWeight(a, b) < dist[b],b為跟頂a有邊連接的頂,則更新頂b的信息:dist[b] = dist[a] + edgeWeight(a, b),pred[b] = a,更新優先隊列中的順序(也可pop時再根據有限度pop)。
    5. 步驟3。

    復雜度分析:

    

 

    實現代碼:https://github.com/Will-Zhu-27/Algorithms-and-Data-Structures/tree/master/graph/shortestPaths/dijkstra

 

Warshall algorithm for transitive closure -- unconnected directed graph

Warshall算法:用於判斷有向圖中頂與頂之間是否能通過邊聯通(包括間接的)。

  用二維數組儲存基礎(直接)邊連接的信息,使用三次循環。

  

    其中i for intermediate, s for source, t for to,循環變量怎么命名的並不重要,重要的是最外圈的循環變量i必須作為判斷的中間變量,改變它的位置會導致算法出錯。我的理解為:算法是基於貪心算法,

    當循環到 i 時,就要得到通過 0 到 i 是否有最短路徑,然后逐漸增大i達到在全部頂中的最短路徑。此問題也可看在知乎上的這個問題的回答:https://www.zhihu.com/question/30955032

 

Floyd-Warshall algorithm for all pairs shortest paths

Floyd-Warshall算法:圖中每個頂到其他頂的最短路徑。

  在Warshall的基礎上稍作改變,二維數組儲存的是頂之間weight的信息。

   

同樣的,最外圈的循環變量i必須作為判斷的中間變量!另外用C實現時,雖然圖里不連接用了∞表示, C中用 INT_MAX / 2 表示, 因為if 判斷時會產生數據溢出問題。

要記錄路徑也只要加個二維數組記錄即可。

復雜度:θ(V3)

代碼:https://github.com/Will-Zhu-27/Algorithms-and-Data-Structures/tree/master/graph/AllPairsShorestPaths/Floyd-Warshall

 

Floyd-Warshall和dijkstra在計算all pairs shorest paths上的優劣:

  循環V次dijkstra也可得到全部頂的最短路徑,復雜度為:O((V2 + V * E)logV)

  Floyd-Warshall復雜度為θ(V3)

  對於sparse graph with positive edge weights(V>>E),Dijkstra用於all pair shortest path更好

    對於dense graph with positive edge weights(E>>V) Floyd-Warshall更好

  


 最小生成樹 Minimum Spanning Tree, MST

  要求:

    undirected weighted graphs

    Graph must be connected   無向非連通圖

  MST特點:

    包括所有的頂

    minimum sum of edge weights,包含連接頂的邊和最小,數量為V-1

    MST中沒有循環(cycles)。

  簡言之,使用最小weight的edge將所有頂連接到。

  

  如果所有的edge的weight不同,那么MST是唯一的。

   計算MST的算法有PrimKruskal

  Prim:通過添加下一個最近的頂完成MST。

    需要使用優先隊列。

    

    准備:dist[V]初值MAX,pred[V]初值NULL,inMst[V]初值FALSE。

    步驟:

    1. 將某一頂 (隨便那個)作為起始點root,dist[ root ] = 0。將全部頂enqueue優先隊列,以dist為優先級。
    2. pop一個頂a,所有與a直接相連的頂b:如果inMst[b]==FALSE && a到b的edge < dist[b],則更新dist[b]等於該edge,更新pred[b]=a,調整優先隊列中的順序。
    3. inMst[a] = TRUE;
    4. 優先隊列為空->結束, 不為空->步驟2

 

    若手工計算,以a為起始點為例,與a相連的有b和c,到b更短,選b。

    

 

    將a和b作為一個整體,與整體相連的有c、d、e,c和d到整體(最短)都是8,隨便選一個,選c。

    

 

    將a和b和c作為一個整體,與整體相連的有e、d、f,到整體最短的是f,選f。

    

    將a和b和c和f作為一個整體,與整體相連的有e、d、g,到整體最短的是d,選d。

    

    

    將a和b和c和f和d作為一個整體,與整體相連的有e、g,到整體最短的是g,選g。

    

    將a和b和c和f和d和g最為一個整體,與整體相連的有e,選e。

    

     復雜度分析:

  

    從算法步驟可以看出復雜度是與V有關的,所以Prim更適合dense graph(E>>V)。

    代碼:https://github.com/Will-Zhu-27/Algorithms-and-Data-Structures/tree/master/graph/Minimum%20Spanning%20Tree/Prim

  Kruskal:通過添加最短的且不構成回路的邊完成MST

    需要使用優先隊列和Union-find 結構。

    Union-find 結構:所有的頂都各自為一個集合,如果因為E[a][b](連接頂a和頂b)是mst中的話,則a和b所在的集合合並,可以以數組表示如下圖。

    

    也可以用樹的形式表示,以樹的形式表示的話,在進行union合並操作時,注意時將小的樹並入大的樹中。

    步驟:

      1.將所有邊根據weight入列優先隊列。將所有頂裝入union-find結構。

      2.從優先隊列中取出一條邊E[a][b](weight最小的)。

      3.如果a和b在同一集合中,則步驟2。如果不再同一集合中,則a和b所在的集合合並,E是mst的一條邊。

      4.當mst邊的數量< V - 1,步驟2。

    若手工計算,以下圖為例:

    

      E[a][b](或者是E[c][e],只要不構成回路,選哪個都行)為mst中的邊。

      

      E[c][e]為mst中的邊。

      

      E[b][c]為mst中的邊。

      

      E[c][f]為mst中的邊。

      

      E[g][f]為mst中的邊。

      

      E[d][f]為mst中的邊,不能是E[c][g]或E[a][e]會構成回路。

      

      已經過所有的頂,mst完成。

     代碼:https://github.com/Will-Zhu-27/Algorithms-and-Data-Structures/tree/master/graph/Minimum%20Spanning%20Tree/Kruskal

 

 

  

 

 

 

 

    

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM