算法導論讀書筆記(22)基本的圖算法

第六部分 圖算法

第22章 基本的圖算法

圖的搜索指的系統化地跟隨圖中的邊來訪問圖中的每個結點
搜索算法可以用來發現圖的結構
圖的兩種表示法分別是鄰接鏈表鄰接矩陣

1. 圖的表示

對於圖G=(V, E)可以用兩種標準表示方法表示:
1. 鄰接鏈表,因爲在表示稀疏圖(邊的條數|E|遠遠小於|V|^2的圖)時非常緊湊而成爲通常的選擇。
2. 鄰接矩陣,在稠密圖(|E|接近|V|^2的圖)的情況下,傾向於該表示法。

鄰接鏈表表示一個包含|V|條鏈表的數組Adj所構成每個結點一條鏈表。對於每個結點,鄰接鏈表Adj[u]包含所有與結點u之間有邊相連的結點v,即Adj[u]包含圖G中所有與u鄰接的結點。
這裏寫圖片描述

這裏寫圖片描述

權重圖是圖中的每條邊都帶有一個相關的權重的圖對鄰接鏈表稍加修改,即可用來表示權重圖

鄰接鏈表的一個潛在缺陷無法快速判斷一條邊(u, v)是否是圖中的一條邊鄰接矩陣克服了這個缺陷,但付出的代價是更大的存儲空間消耗。鄰接矩陣的空間需求皆爲θ(V^2)

無向圖的鄰接矩陣是一個對稱矩陣

鄰接矩陣表示法更爲簡單,因此在圖規模比較小時,我們可能更傾向於使用鄰接矩陣表示法。

2.廣度優先搜索

該搜索算法是許多重要的圖算法的原型。Prim的最小生成樹算法和Dijkstra的單源最短路徑算法都使用了類似廣度優先搜索的思想。

在廣度優先搜索樹裏從結點s到結點v的簡單路徑所對應的就是圖G中從結點s到結點v的“最短路徑”。該算法既用於有向圖,也可以用於無向圖

廣度優先搜索算法需要在發現所有距離源結點s爲k的所有結點之後纔會發現距離源結點s爲k+1的其他結點

這裏寫圖片描述

u.d記錄的是廣度優先搜索算法所計算出的從源點s到結點u之間的距離
u.π記錄u的前驅結點

BFS(G, s)
    for each vertex u∈G.V - {s}
        u.color = White
        u.d = ∞
        d.π = NIL
    s.color = Gray
    u.d = 0
    d.π = NIL
    Q = ∅
    EnQueue(Q, s)
    while Q != ∅
        u = DeQueue(Q)
        for each v∈G.Adj[u]
            if v.color == White
                v.color = Gray
                v.d = u.d + 1
                v.π = u
                EnQueue(Q, v)
        u.color = Black

3.深度優先搜索

深度優先搜索總是對最近才發現的結點v出發邊進行探索直到該結點的所有出發邊都被發現爲止一旦結點v的所有出發邊都被發現,搜索則“回溯”到v的前驅結點,來搜索前驅結點的出發邊

廣度優先搜索的前驅子圖形成一棵樹,而深度優先搜索的前驅子圖可能由多棵樹組成

深度優先搜索的前驅子圖形成一個由多棵深度優先樹構成的深度優先森林。森林Eπ中的邊仍然稱爲樹邊。

這裏寫圖片描述
這裏寫圖片描述

DFS(G)
    for each vertex u∈G.V
        u.color = White
        u.π = NIL
    time = 0
    for each vertex u∈G.V
        if u.color == White
            DFS-Visit(G, u)
DFS-Visit(G, u)
    time = time + 1         // white vertex u has just been discovered
    u.d = time
    u.color = Gray
    for each v∈G.Adj[u]     // explore edge(u, v)
        if v.color == White
            v.π = u
            DFS-Visit(G, v)
    u.color = Black         // black u, it is finished
    time = time + 1
    u.f = time

深度優先搜索算法的運行時間爲θ(V+E)。

深度優先搜索的性質

最基本的性質是,其生成的前驅子圖Gπ形成一個由多棵樹所構成的森林。
另一個重要性質是,結點的發現時間和完成時間具有所謂的括號化結構。

邊的分類

深度優先搜索的另一個有趣的性質是,可以通過搜索來對輸入圖G=(V, E)的邊進行分類:
1. 樹邊:爲深度優先森林Gπ中的邊。如果結點v是因算法對邊(u, v)的探索而首先被發現,則(u, v)是一條樹邊。
2. 後向邊:後向邊(u, v)是將結點u連接到其在深度優先樹中(一個)祖先結點v的邊。由於有向圖中可以有自循環,自循環也被認爲是後向邊。
3. 前向邊:是將結點u連接到其在深度優先樹中一個後代結點v的邊(u, v)。
4. 橫向邊:指其他所有的邊。

4. 拓撲排序

對於一個有向無環圖G = (V,E)來說,其拓撲排序是G中所有結點的一種線性次序,該次序滿足如下條件:如果圖G包含邊(u, v),則結點u在拓撲排序中處於結點v的前面。

拓撲排序就是將節點按完成時間進行降序排序。

這裏寫圖片描述

Topological-Sort(G)
    call DFS(G) to compute finishing times v.f for each vertex v as each vertex is finished, insert it onto the front of a linked list
    return  the linked list of vertices

5. 強連通分量

如果一個無向圖中每個頂點從所有其他頂點都是可達的,則稱該圖是連通的。圖的連通分量是頂點在“從……可達”關係下的等價類。
如果一個有向圖中任意兩個頂點互相可達,則該有向圖是強連通的。
這裏寫圖片描述

Strongly-Connected-Components(G)
    call DFS(G) to compute finishing times u.f for each vertex u
    compute GT
    call DFS(GT), but in the main loop of DFS, consider the vertices in order of decreasing u.f(as computed in line 1)
    output the vertices of each tree in the depth-frist forest formed in line3 as a separate strongly connected component
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章