ch06圖形結構

Download Report

Transcript ch06圖形結構

第六章
圖形(Graph)結構
6-1 圖形的基本概念
6-2 圖形的表示法
6-3 圖形的追蹤
6-4 擴張樹
6-5 圖形最短路徑
6-6 AOV 網路與拓樸排序
written by Wei-ShenLai
1
6-1
圖形的基本概念
 圖形結構是一種探討兩個頂點間是否相連的一種關係圖, 在圖形
中連接兩頂點的邊若填上加權值( 也可以稱為花費值) , 這類圖形
就稱為「網路」。
 圖形除了被活用在資料結構中最短路徑搜尋、拓樸排序外,還能應
用在系統分析中以時間為評核標準的計劃評核術(Performance
Evaluation and Review Technique, PERT),它是一種將系統作
業流程依進行的優先順序繪製成網路, 來追蹤工作進度的評核工
具。
written by Wei-ShenLai
2
6-1-1
認識圖形的起源
 問題的由來:
C
c
A
e
Kneiphof
a
B
A
D
B
b
a
e
D
f
B
f
b
g
d
7
C
A
8
written by Wei-ShenLai
g
1
 Euler定義一個頂點(Vertex)的分支度為附著於
其上的邊。
 而後他證明了若且唯若每一個頂點的度數為偶數則
存在一種走法,從某一點出發,而能經過每一個邊
最後回到原點的充要條件的走法之為尤拉走法
(Eulerian Walk or Eulerian Cycle)。
 從某一點出發,而能經過每一個邊,不一動要回到
起點的充要條件的走法之為尤拉鍊(Eulerian
Chain)。僅允許有兩個頂點的分支度為奇數。其
餘頂點分支度均為偶數。
d
2
 在Koenigsberg,有一條prgal河,河中有
Kneiphof島。在圖中以此河為界有4塊土
地。這些分隔的士地以a至g七條橋相互連
結,而土地部份以A到D來標記,而七橋
問題就是判斷從其中一區域出發。是否有
可能通過所有的橋而且只經過一次,最後
再回到原出發點。
C
c
6
 何謂Koenigsberg橋樑問題:
3
 1736年數學家Euler利用圖形來解決古典
的Koenigsberg橋樑問題。
D
5
E
4
3
6-1-2
圖形專業術語的介紹(Terminology)
 圖形(graph)是由頂點(vertice)和邊(edge)所組成,
以G=(V,E)來表示;其中V 為所有頂點的集合,
E 為所有邊的集合。
 圖形分為兩類:
無向圖(Undirected Graph):
V={A,B,C,D,E}
E={(A,B) ,(A,E) ,(B,C),(B,D),(C,D),(C,E),(D,
E)}
邊是沒有方向性的,沒有方向性的邊以( ) 表
示
(A,B)=(B,A)
A
C
B
D
E
有向圖(Directed Graph):
V={A,B,C,D,E}
E={<A,B>,<B,C>,<C,D>,<C,E>,<E,D>,<D,
B>}
邊都是有方向性,以< > 來表示
<A,B>≠<B,A>
〈頭部,尾部〉
A
written by Wei-ShenLai
B
C
D
E
4
完整圖形(Complete Graph)
 假設圖形G有N個頂點。
 無向圖形中,完整圖共有N(N-1)/2個邊。C2N
 有向圖形中,完整圖共有N(N-1)個邊。 P2N
A
A
B
C
D
written by Wei-ShenLai
E
B
C
D
E
5
子圖(Subgraph)
 G’如果為G的子圖,必須滿足:
 V   V且E  E
G'與G''均G的子圖,但是G'''不為G的子圖。
A
A
B
C
D
E
G
written by Wei-ShenLai
A
B
C
D
G'
D
E
G''
C
D
E
G'''
6
路徑(Path)
 路徑:兩個不同頂點間所經過的邊稱為路徑,如圖G , A 到E 的路徑有{(A,B),
(B,E)}及{(A,B),(B,C),(C,D),(D,E)}等等。
 路徑長度: 路徑上所包含邊的總數為路徑長度。
A
A
B
C
D
written by Wei-ShenLai
E
B
C
D
E
7
簡單路徑(Simple Path)
 簡單路徑:除了起點和終點可能同一個頂點外,路徑上所經過的頂點均不同,
也就是說路徑沒有重疊,就稱為簡單路徑。
A
A
B
C
D
E
簡單路徑
written by Wei-ShenLai
B
C
D
E
不為簡單路徑
8
循環(Cycle)
 循環:起始頂點及終止頂點為同一個點的簡單路徑稱為循環。如上圖G ,
{(A,B),(B,D),(D,E),(E,C),(C,A)}起點及終點都是A ,所以是 一個循環路徑。
A
A
B
A
C B
D
E
簡單路徑
循環
written by Wei-ShenLai
C B
D
E
簡單路徑
循環
C
D
E
簡單路徑
不為循環
9
相連(Connected)與強相連(Strongly Connected)
 相連:在無向圖形中,若頂點Vi 到頂點Vj 間存在路徑,則Vi 和Vj
是相連的。
 強相連:在有向圖形中,若頂點Vi 到頂點Vj 間存在路徑及頂點Vj
到頂點Vi 間存在路徑,則Vi 和Vj是強相連的。
 相連圖形:如果圖形G 中,任兩個頂點均為相連,則此圖形稱為相
連圖形, 否則稱為非相連圖形。
written by Wei-ShenLai
10
相連單元(Connected Component)
 相連單元:圖形中相連在一起的最大子圖總數。如下圖可以看做是2個相連單
元:
A
D
C
E
B
written by Wei-ShenLai
11
分支度(degree)與入/出分支度(in degree/out degree)
 分支度:在無向圖形中,一個頂點
所擁有邊的總數為分支度。如圖G ,
A 頂點的分支度為4 。
A
B
C
D
 入/出分支度:在有向圖形中,以
頂點V 為箭頭終點的邊之個數為入
分支度,反之由V 出發的箭頭總數
為出分支度。如圖,A 的入支度為1 ,
出分支度為3 。
A
B
C
D
written by Wei-ShenLai
E
E
12
6-1-3 認識特殊的圖形
 複線圖(multigraph)
圖形中任意兩頂點只能有一條邊,
如果兩頂點間相同的邊有2 條以
上( 含2 條) ,則稱它為複線圖,
以圖形嚴格的定義來說,複線圖
應該不能稱為一種圖形。請看下
圖:
 bipartite graph
有一圖形G = ( V , E ) ,如果能
將頂點分成兩個沒有交集的集合
V1 及V2,則對於所有邊的集合E
中的每一個邊e ( x , y ) ,如果x
屬於V1的其中一個點, 則y 必定
屬於V2集合中的一點。有這種關
係的圖形我們稱為bipartite
graph 。例如下圖G
V1={A 、C 、E 、G}
V2={B 、D、F 、H}
written by Wei-ShenLai
D
A
E
B
D
A
E
F
G
H
E
B
13
6-2 圖形的表示法
6-2-1 相鄰矩陣法(adjacency matrix)
 圖形有四種常見的表示法, 在本節中將分別為您詳細介紹。
 圖形A 有n 個頂點,以n * n 的二維矩陣表示。此矩陣的定義如下:

1, 若(i, j)  E
A(i, j )  
0, 若(i, j)  E
特性:
對無向圖形而言,相鄰矩陣一定是對稱的,而且對角線一定為0 。有向圖形則
不一定是如此。
A(i, j )
在無向圖形中,任一節點i 的分支度為  ,就是第i 列所有元素的和。在
有向圖形中,節點i 的出分支度為  A(i, j),就是第i 列所有元素的和,而入分支
A(i, j )
度為  ,就是第j 行所有元素的和。
 用相鄰矩陣法表示圖形共需要n 2空間,由於無向圖形的相鄰矩陣一定是具有
對稱關係, 所以扣除對角線全部為零外, 僅需儲存上三角形或下三角形的資
料即可,因此僅需n ( n - 1 ) / 2 空間。
n
i 1
n
n
i 1
i 1
written by Wei-ShenLai
14
相鄰矩陣法(adjacency matrix)
1
2
3
4
written by Wei-ShenLai
5
1
2
3
4
5
1
0
1
0
0
1
2
1
0
1
1
0
3
0
1
0
1
1
4
0
1
1
0
1
5
1
0
1
1
0
15
相鄰矩陣法(adjacency matrix)
2
4
written by Wei-ShenLai
1
3
1
2
3
4
1
0
1
0
0
2
1
0
0
0
3
0
1
0
1
4
0
1
0
0
16
6-2-2 相鄰串列法(adjacent list)
 此表示法是以串列結構來表示圖形, 有點類似相鄰矩陣, 不過忽
略掉矩陣中0 的部份,直接把1 的部份放入節點裡。如此一來可以
有效避免浪費儲存空間。
相鄰串列特性
每一個頂點使用一個串列。
 在無向圖中, n 頂點e 邊共需n 個串列首節點及2 * e 個節點( 對稱);
有向圖則需n 個串列首節點及e 個節點。在相鄰串列中,計算所有頂點
分支度所需的時間複雜度O ( n + e ) 。
我們直接來看上一小節的兩個範例, 使用相鄰串列該如何表示。
struct list
{
int val;
struct list *next;
};
typedef struct list node;
typedef node *link;
struct list head[6];
written by Wei-ShenLai
17
相鄰串列法(adjacent list)
1
2
3
4
written by Wei-ShenLai
5
V1 ●
2 ●
5 ●
V2 ●
1 ●
3 ●
4 ●
Null
V3 ●
2 ●
4 ●
5 ●
Null
V4 ●
2 ●
3 ●
5 ●
Null
V5 ●
1 ●
3 ●
4 ●
Null
Null
18
相鄰串列法(adjacent list)
2
1
V1 ●
2 ●
V2 ●
3 ●
V3 ●
4
written by Wei-ShenLai
3
V4 ●
Null
4 ●
Null
Null
3 ●
Null
19
【範例:6 . 2 . 4 】
 舉例說明如何以相鄰矩陣法及相鄰串列法來表示圖形?使用這兩種方法的優缺
點各為何?(研究所試題)
 【解答】
優點
缺
點
相鄰矩陣法
1.實作簡單
2.計算分支度相當方便
3.要在圖形中加入新邊,
這個表示法的插入與刪除
相當簡易
1.如果頂點與頂點間的路
徑不多時,易造成稀疏矩
陣,而浪費空間
2.計算所有頂點的分支度
時,其時間複雜度為O(n2)
相鄰串列法
1.和相鄰矩陣相比較節省
空間
2.計算所有頂點的分支度
時,其時間複雜度為
O(n+e),較相鄰矩陣法來
得快
1.欲求入分支度時,必須
先求其反轉串列
2.圖形新邊的加入或刪除
會更動到相關的串列鏈結,
較為麻煩費時
written by Wei-ShenLai
20
6-2-3 相鄰多元串列法(adjacency multilist)
 上面我們介紹了兩個圖形表示法都是從頂點的觀點出發,但如果我們要處理的
是「邊」則必須使用相鄰多元串列, 相鄰多元串列是處理無向圖形的另一種
方法。
 相鄰多元串列的節點是存放邊線的資料, 其結構如下:
M
V1
V2
LINK1
LINK2
記錄單元 邊線起點 邊線終點 起點指標 終點指標
M:是記錄該邊是否被找過的一個位元之欄位
V1及V2:是所記錄的邊的起點與終點
LINK1:在尚有其它頂點與V1 相連的情況下,此欄位會指向下一個與V1
相連的邊節點,如果已經沒有任何頂點與V1 相連時,則指向NIL。
LINK2:在尚有其它頂點與V2相連的情況下,此欄位會指向下一個與V2相
連的邊節點,如果已經沒有任何頂點與V2相連時,則指向NIL。
written by Wei-ShenLai
21
相鄰多元串列法(adjacency multilist)
1
2
3
4
written by Wei-ShenLai
5
head
1 M1
2 M1
3 M3
4 M4
5 M2
M1
1 2
M2 M3
M2
1 5
Nil M6
M3
2 3
M4 M5
M4
2 4
Nil M5
M5
3 4
M6 M7
M6
3 5
Nil M7
M7
4 5
Nil Nil
22
相鄰多元串列法(adjacency multilist)
2
4
written by Wei-ShenLai
1
3
head
1 M1
2 M2
3 Nil
4 M4
M1
1 2
Nil Nil
M2
2 3
M3 M4
入分支度
M3
2 4
Nil Nil
M4
4 3
Nil Nil
head
1 Nil
2 M1
3 M2
4 M3
23
6-2-4 索引表格法(Indexed Table)
 索引表格圖形表示法, 是一種用一個一維陣列, 依序儲存與各頂點相鄰的所
有頂點,並建立索引表格,來記錄各頂點在此一維陣列中第一個與該頂點相鄰
的位置。也就是說若圖形有n 個頂點,就必須建立n 個索引位置的表格,來記
錄一維陣列中分別與這n 個頂點第一個相鄰的頂點位置。我們以下圖來說明索
引表格法的實例。
A
B
D
C
A
1
B
4
C
7
D
10
1
2
3
4
5
6
7
8
9 10 11 12
B
C
D
A
C
D
A
B
D
written by Wei-ShenLai
A
B
C
24
6-3 圖形的追蹤
 如同樹一般, 圖形也有一套特別的走訪方式。圖形是從某一個頂
點V1開始,走訪可以經由V1到達的頂點,接著再走訪下一個頂點
直到全部的頂點走訪完畢為止。在走訪的過程中可能會重複經過某
些頂點及邊線。經由圖形的走訪可以判斷該圖形是否連通, 並找
出連通單元及路徑。
 圖形走訪的方法有兩種: 「先深後廣走訪」及「先廣後深走訪」。
written by Wei-ShenLai
25
先深後廣搜尋法(DFS)
struct list
{
int val;
struct list *next;
};
typedef struct list node;
typedef node *link;
struct list* head[9];
1 ●
2 ●
3 ●
2 ●
1 ●
4 ●
5 ●
Null
3 ●
1 ●
6 ●
7 ●
Null
4 ●
2 ●
5 ●
5 ●
2 ●
4 ●
8 ●
Null
6 ●
3 ●
7 ●
8 ●
Null
void dfs(int current) /* 深度優先走訪副程式*/
{
link ptr;
run[current]=1;
printf("[%d] ",current);
ptr=head[current]->next;
while(ptr!=NULL)
{
7 ●
3 ●
6 ●
Null
8 ●
5 ●
6 ●
Null
Null
Null
if (run[ptr->val]==0) /* 如果頂點尚未走訪, */
dfs(ptr->val); /* 就進行dfs 的遞迴呼叫*/
}
}
ptr=ptr->next;
written by Wei-ShenLai
26
6-3-1 先深後廣搜尋法(DFS)
 先深後廣走訪的方式
有點類似前序走訪。
是從圖形的某一頂點
開始走訪,被拜訪過
的頂點就做上已拜訪
的記號。接著走訪此
頂點的所有相鄰且未
拜訪過的頂點中的任
意一個頂點,並做上
已拜訪的記號,再以
該點為新的起點繼續
進行先深後廣的搜尋。
 以堆疊實作。
written by Wei-ShenLai
1
2
3
4
5
堆疊內容
結果
5
2
1
5
4
3
5
4
5
4
1,2,3
5
4
5
5
1,2,3,4
5
4
5
1,2
1,2,3,4,5
27
先廣後深搜尋法(BFS)
struct list
{
int val;
struct list *next;
};
typedef struct list node;
typedef node *link;
struct list* head[9];
void bfs(int v){
node_pointer w;
queue_pointer front,rear;
front=rear=NULL;
printf("%d",v);
visited[v]=TRUE;
addq(&front,&rear,v);
while(front){
v=deleteq(&front);
for(w=graph[v];w;w=w-<link)
if(!visited[w->vertex]){
printf("%d",w->vertex);
}
}
written by Wei-ShenLai
}
1 ●
2 ●
3 ●
2 ●
1 ●
4 ●
5 ●
Null
3 ●
1 ●
6 ●
7 ●
Null
4 ●
2 ●
5 ●
5 ●
2 ●
4 ●
8 ●
Null
6 ●
3 ●
7 ●
8 ●
Null
7 ●
3 ●
6 ●
Null
8 ●
5 ●
6 ●
Null
Null
Null
addq(&front,&rear,w->vertex);
visited[w->vertex]=TRUE;
28
6-3-2 先廣後深搜尋法(BFS)
 先廣後深的走訪方式
則是以佇列及遞迴技
巧來走訪。先廣後深
是從圖形的某一頂點
開始走訪,被拜訪過
的頂點就做上已拜訪
的記號。接著走訪此
頂點的所有相鄰且未
拜訪過的頂點中的任
意一個頂點, 並做上
已拜訪的記號, 再以
該點為新的起點繼續
進行先廣後深的搜尋。
written by Wei-ShenLai
1
2
3
4
5
住列內容
結果
2
5
1
5
3
4
3
4
3
4
1,2,5
4
3
4
4
1,2,5,3
3
4
4
1,2
1,2,5,3,4
29
6-3-3 圖形追蹤的應用
 判斷此圖形是否相連
圖形追蹤可以用來判斷圖形是否連通(connected),若我們選定圖形
中的V 為起始頂點,以先深後廣或先廣後深拜訪所有相鄰的頂點,如
果所有的頂點都被拜訪到, 則稱此圖形是連通的。
 找出圖形的相連單元(Connected Component)
選用先深後廣或先廣後深追蹤, 以圖形中尚未被拜訪過的頂點中任
意一點作為起始點,每經過一次先深後廣或先廣後深追蹤,就能找到
一個連通單元;接著,再由那些剩下且未被拜訪過頂點中任意一點作
為起始點, 繼續進行先深後廣或先廣後深追蹤, 一直到做完全部的
頂點。
written by Wei-ShenLai
30
6-4 擴張樹 (Spanning Tree)
 找出圖形的擴張樹,也是圖形追蹤的一種應用。所謂擴張樹(也有
值樹、跨越樹、花費樹等說法)就是把一個圖形中的所有頂點以最
少的邊連接起來,而且不能形成迴圈(cycle)的樹狀結構。所以一個
有n 頂點的無向圖形擴張樹,則一定有n-1個邊。以一個嚴謹的定
義來說,假設圖形G=(V,E),將所有的邊分成兩個集合T及B,其
中T 為拜訪過程中所經過的邊,B則為拜訪過程未經過的邊。由於
擴張樹是由所有頂點及拜訪過程經過的邊所組成,令S=(V,T)為圖
形G 中的擴張樹(spanning tree),該擴張樹具有底下幾個特點:
written by Wei-ShenLai
31
DFS擴張樹
1
1
2
3
2
3
4
5
4
DFS擴張樹
1
2
2
1
3
3
1 ●
2 ●
5 ●
2 ●
1 ●
3 ●
4 ●
Null
3 ●
2 ●
4 ●
5 ●
Null
4 ●
2 ●
3 ●
5 ●
Null
5 ●
1 ●
3 ●
4 ●
Null
Null
4
4
5
DFS擴張樹
written by Wei-ShenLai
32
BFS擴張樹
1
1
2
2
3
3
4
4
5
BFS擴張樹
1
4
1
2
3
1 ●
2 ●
5 ●
2 ●
1 ●
3 ●
4 ●
Null
3 ●
2 ●
4 ●
5 ●
Null
4 ●
2 ●
3 ●
5 ●
Null
5 ●
1 ●
3 ●
4 ●
Null
Null
2
4
3
5
BFS擴張樹
written by Wei-ShenLai
33
(MST)最小 擴張樹(Minimum Cost Spanning Tree)
 假設我們在樹的邊加上一個權重(weight)值,這種圖形就成為「加權圖形
(Weighted Graph)」。如果這個權重值代表兩個頂點間的距離(distance)或成
本(Cost),這類圖形就稱為網路Network)。如下圖所示:
1
1
6
2
3
5
4
5
1
1
1
2
6
2
2
4
5
3
1
5
3
2
4
4
3
5
1
5
written by Wei-ShenLai
5
34
Prim演算法:
 Prime與Kruskal類似,Kruskal建
立的過程是連通單元,而Prime建立
的過程是樹狀結構。
 Prime的想法:
選取一的頂點當成樹T。
每次選取一個成本為最小的邊
(u,v)。且u或v頂點僅一個在T中。
(如此才不會造成環路。
加入樹T中。直到T中有n-1邊為
止。
實作想法:
將圖形G中的E(G)依遞增順序排
序。以利邊的選取。O
(e*log(e))
一個陣列記錄T中的頂點:V
(T)。一個陣列記錄G中未納
入T中的節點U(G)。
每此搜尋E(G)中未處理的邊
(u,t),u在U(G)中t在V(T)中。
6
A
12
3
8
F
10
16
C
5
11
E
7
D
9
B
6
A
B
C
10
D
A
6
B
E
12
A
B
A
F
C
3
5 D
10
12 E
F
8
5 D
10
B
12 E
C 7 8
F
A
6
B
3
C
A
6
B
3
5
C
D
written by Wei-ShenLai
35
Prim演算法
6
A
12
3
8
F
10
16
E
B
11
9
候選邊
C
5
7
D
成本
結果
U
-
-
-
{B,C,D,E,F}
(A,B),(A,F),(A,E)
6,12,10
加入(A,B){C,D,E,F}
12,10,3,5,
加入(B,C){D,E,F}
(A,F),(A,E),(B,C),(B,D),(B,F)
8
12,10,5,8,
加入(B,D){E,F}
(A,F),(A,E),(B,D),(B,F), (C,D)
7
(A,F),(A,E),(B,F),(C,D),(D,F 12,10,8,7,
加入(B,F){E}
),(D,E)
11,9
12,10,11,9
加入(D,E){}
(A,F),(A,E),(D,F),(D,E),(F,E)
,16
written by Wei-ShenLai
V
{A}
{A,B}
{A,B,C}
{A,B,C,D}
{A,B,C,D,F}
{A,B,C,D,F,E}
36
【練習:Prim演算法】
0
28
候選邊
1
10
6
5
2
1
5
14
16
6
2
24
18
25
4
12
4
22
3
3
written by Wei-ShenLai
(0,5),(0,1)
(4,5),(0,1)
(3,4),(4,6),(0,1)
(3,2),(3,6),
(4,6),(0,1)
(1,2),(3,6),
(4,6),(0,1)
(1,6),(3,6),
(4,6),(0,1)
成本
10,28
25,28
22,24,28
12,18,
24,28
16,18,
24,28
14,18,
24,28
結果
U(G)陣列
V(T)陣列
加入
加入
{1,2,3,4,5,6}
{1,2,3,4,5,6}
{1,2,3,4,6}
{1,2,3,6}
{0}
{0,5}
{0,5,4}
{0,5,4,3}
加入
{1,6}
{0,5,4,3,2}
加入
{6}
{0,5,4,3,2,1}
加入
{}
{0,5,4,3,2,1,6}
37
【練習:Prim演算法】
16 1
1
11 4 3
21
3
written by Wei-ShenLai
14
18
成本
16,19,21
19,21,6,
5,11
19,21,6,
11,10
19,21,11
10,14,18
19,21,10
14,18,33
5
6
33
(1,2),(1,3),(1,6)
(1,3),(1,6),(2,4)
(2,5),(2,6)
(1,3),(1,6),(2,4)
(2,6),(5,4)
(1,3),(1,6),(2,6)
(5,4),(4,6),(3,4)
(1,3),(1,6),(5,4)
(4,6),(3,4),(3,6)
2 5
6
19
候選邊
2
5
10
4
結果
U(G)陣列
V(T)陣列
-
{2,3,4,5,6}
{3,4,5,6}
{1}
{1,2}
加入
{3,4,6}
{1,2,5}
加入
{3,6}
{1,2,5,4}
加入
{3}
{1,2,5,4,6}
加入
{}
{1,2,5,4,6,3}
38
Kruskal演算法:
 每次在圖形中選取成本為最小的邊,加入樹中且該邊的加入不會造
成環路。所以G如果有n個頂點僅需選取n-1個邊即可建立最小生成
樹T。
非連通圖形不可能存在最小成本生成樹。
演算法的實作:
將圖形G中的E(G)依遞增順序排序。以利邊的選取。O(e*log(e))
每次將邊加入生成樹時必須判斷是否造成環路。
環路的判斷:如果有一個邊(v,w)加入T中。利用union_find()判斷v,w
是否在同一個集合。可將(v,w)看成union(v,w)。
 如果在同一個集合則該邊加入會造成環路。
written by Wei-ShenLai
39
Kruskal演算法
邊
(B,C)
6
A
B
(B,D)
3
12 8
(A,B)
10
5
F
C (C,D)
16
11
7
(B,F)
E
D
(D,E)
9
(A,E)
(D,F)
(A,F)
(E,F)
written by Wei-ShenLai
成本
3
5
6
7
8
9
10
11
12
16
結果
加入
加入
加入
環路
加入
加入
不考慮
不考慮
不考慮
不考慮
T集合
{B,C}
{B,C,D}
{B,C,D,A}
{B,C,D,A}
{B,C,D,A,F}
{B,C,D,A,F,E}
40
【練習: Kruskal演算法】
0
28
1
10
3
5
6
1
4
14
16
6
2
24
18
25
2
12
4
22
5
written by Wei-ShenLai
邊
成本
結果
T'集合
(0,5)
(2,3)
(1,6)
(1,2)
(3,6)
(3,4)
(4,6)
(4,5)
(0,1)
10
12
14
16
18
22
24
25
28
加入
加入
加入
加入
環路
加入
環路
加入
不考慮
{0,5}
{0,5},{2,3}
{0,5},{2,3},{1,6}
{0,5},{2,3,1,6}
{0,5},{2,3,1,6}
{0,5},{2,3,1,6,4}
{0,5},{2,3,1,6,4}
{0,5,2,3,1,6,4}
3
41
【練習: Kruskal演算法】
16 4
1
21
3
11
1 5
2
6
19
33
3
2
14
18
5
written by Wei-ShenLai
5
6
10
4
邊
成本
結果
(2,5)
(2,4)
(4,5)
(2,6)
(4,6)
(1,2)
(3,4)
(1,3)
(1,6)
(3,6)
5
6
10
11
14
16
18
19
21
21
加入
加入
環路
加入
環路
加入
加入
不考慮
不考慮
不考慮
T'集合
{2,5}
{2,5,4}
{2,5,4}
{2,5,4,6}
{2,5,4,6}
{2,5,4,6,1}
{2,5,4,6,1,3}
42
Sollin演算法:
 Sollin的想法:
第一階段:替每個頂點選取最小的邊。形成樹林。
第二階段:依序選取未處理的邊,且該邊的頂點分屬於不同樹。以連
結兩棵不同的樹。
形成一棵樹為止。
實作想法:
將圖形G中的E(G)依遞增順序排序。以利邊的選取。O(e*log(e))
在第一階段可利用union_find()決定樹林的樣子。
第二階段:依遞增順序搜尋未處理的邊,如果該邊的頂點分屬不同的樹。
則連結兩棵不同的樹。
written by Wei-ShenLai
43
Sollin演算法
6
A
9
16
邊
(A,B)
(C,D)
(B,F)
(D,E)
(A,F)
(A,E)
(D,F)
(B,C)
(B,D)
(E,F)
6
7
8
9
9
10
11
13
14
16
C
14
11
9
第一階段
成本
A,B
C,D
F
E
written by Wei-ShenLai
13
8
F
10
E
B
7
D
結果
邊
(A,B)
(C,D)
(B,F)
(D,E)
(A,F)
(A,E)
(D,F)
(B,C)
(B,D)
(E,F)
第二階段
成本
結果
不考慮
6
不考慮
7
不考慮
8
不考慮
9
環路,放棄
9
加入
10
11
13
14
16
44
【練習:Sollin演算法】
第一步
0
28
1
10
1
5
2
1
2
14
16
6
2
24
18
25
1
12
4
22
1
written by Wei-ShenLai
3
第二步
邊
成本
邊
成本
(0,5)
(2,3)
(1,6)
(1,2)
(3,6)
(3,4)
(4,6)
(4,5)
(0,1)
10
12
14
16
18
22
24
25
28
(0,5)
(2,3)
(1,6)
(1,2)
(3,6)
(3,4)
(4,6)
(4,5)
(0,1)
10
12
14
16
18
22
24
25
28
Forest
Forest
{0,5},{1,6}
,{2,3,4}
{0,5},{1,6,2,3,4}
{0,5,1,6,2,3,4}
45
【練習:Sollin演算法】
第一步
16
1
21
2
11
6
19
33
3
5
14
18
written by Wei-ShenLai
5
6
10
4
第二步
邊
成本
邊
成本
(2,5)
(2,4)
(4,5)
(2,6)
(4,6)
(1,2)
(3,4)
(1,3)
(1,6)
(3,6)
5
6
10
11
14
16
18
19
21
33
(2,5)
(2,4)
(4,5)
(2,6)
(4,6)
(1,2)
(3,4)
(1,3)
(1,6)
(3,6)
5
6
10
11
14
16
18
19
21
33
Forest
Forest
{1,2,3,4,5,6}
{1,2,3,4,5,6}
46
6-5 圖形最短路徑
 在一個有向圖形G = ( V , E ) , G 中每一個邊都有一個比例常數
W(Weight)與之對應,若想求G圖形中某一個頂V0 到其它頂點的
最少W 總和之值,這類問題就稱為最短路徑問題(The Shortest
Path Problem)本節將探討單點對全部頂點的最短距離及所有頂點
兩兩之間的最短距離。
written by Wei-ShenLai
47
6-5-1 單點對全部頂點




一個頂點到多個頂點通常使用Dijkstra演算法求得, Dijkstra的演算
法如下:
假設S={Vi|Vi∈V},Vi在已發現的最短路徑,其中V0∈ S 是起點。
假設w∉ S ,定義Dist(w)是從V0 到w的最短路徑,這條路徑除了w外必屬於S。且有下列幾點特性:
 如果u是目前所找到最短路徑之下一個節點,則u 必屬於V-S集合中最小花費成本的邊。
 若u 被選中,將u 加入S 集合中,則會產生目前的由V0到u最短路徑,對於w , DIST(w)被改變成
 DIST(w)← Min{DIST(w),DIST(u)+COST(u,w)}
 從上述的Algorithm我們可以推演出如下的步驟:
 【步驟1 】










G=(V,E)
D[k]=A[F,k]其中k 從1 到N
S={F}
V={1,2,......N}
D 為一個N 維陣列用來存放某一頂點到其他頂點最短距離
F 表示起始頂點
A[F,I]為頂點F 到I 的距離,
V 是網路中所有頂點的集合。
E 是網路中所有邊的組合。
S 也是頂點的集合,其初始值是S={F}。
 【步驟2 】
 從V ─ S 集合中找到一個頂點x ,使D[x]的值為最小值,並把x 放入S
 集合中。
 【步驟3 】




依下列公式
D[I]=min(D[I],D[x]+A[x,I])其中(x,I)∈Ε 來調整D 陣列的值,其中I 是指
x 的相鄰各頂點。
【步驟4 】
 重複執行【步驟2 】, 一直到V ─ S 是空集合為止。
 我們直接來看一個例子。
written by Wei-ShenLai
48
12
12
4
14
5
0
步驟
1
2
3
4
5
S
0
5
∞
5,1
∞
5,1,4
14+12=26
5,1,4,2
26
5,1,4,2,3
26
written by Wei-ShenLai
1
12
12
12
12
12
6
2
15
8
1
16
【範例:6 . 5 . 1 】
20
10
3
2
3
4
∞
20
14
12+6=18
20
12+16>14
18
20
14
18
18+10>20
14
18
20
14
5
0
0
0
0
0
選擇
1
4
2
3
0
49
【範例】
Boston
San
Francisco
Chicago
Denver
800
1
300
2
3
1200
1400
New
York
900
7
1000
New Orleans
S
250
5
1700
Los Angeles
步驟
4
1000
1000
0
1500
6
Miami
0
1
2
3
4
5
1500
250+1000
=1250
0
250
0
250
6
7
1
4
∞
∞
∞
2
4,5
∞
∞
∞
3
4,5,6
∞
∞
∞
1250
0
250
4
4,5,6,3
∞
∞
1250+1200
=2450
1250
0
250
1150
1650
7
5
4,5,6,3,7
2450
1250
0
250
1150
1650
2
2450
1250
0
250
1150
1650
1
2450
1250
0
250
1150
1650
2450
1250
0
250
1150
1650
6
7
1650+1700
∞
=3350
2450+1000 2450+800
4,5,6,3,7,2
>3350
=3250
4,5,6,3,7,2 3250+300
3250
,1
>3350
3350
3250
written by Wei-ShenLai
∞
∞
250+900 250+1400
=1150
=1650
1150+1000
1150
>1650
選擇
5
6
3
50
6-5-2 所有頂點兩兩之間的最短距離
 Dijkstra的方法只能求出某一點到其他頂點的最短距離,如果要求
出圖形中任兩點甚至所有頂點間最短的距離,就必須使用Floyd 演
算法。
 Floyd 演算法定義:
Ak[i][j]=min{Ak-1[i][j],Ak-1[i][k]+Ak-1[k][j]}, 1≤ i , j≤ n
其中Ak[ i ] [ j ] 為從i 到j 不以註標大於k 之頂點為間接路徑頂點時之最
短路徑的花費。
A0[i][j]=COST[i][j] (即A0 便等於COST)
A0為頂點i 到j 間的直通距離。
An[ i , j ] 代表i 到j 之最短路距離,即An 便是我們所要求的最短路徑成
本矩陣。
for(k=0;k>n;k+=)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(A[i][k]+A[k][j]<A[i][j])
A[i][j]=A[i][k]+A[k][j];
written by Wei-ShenLai
51
【範例:6 . 5 . 2 】
 試以Floyd 演算法求得下圖各頂點間的最短路徑。
1
2
4
3
11
2
3
A
1
2
3
A
1
0
4 11
2
6
0
3
A
written by Wei-ShenLai
0
1
2
1
2
3
1
0
4
6
2
2
6
0
2
3 ∞ 0
3
3
7
0
1
2
3
3
1
2
3
A
1
0
4 11
1
0
4
6
2
6
0
2
2
5
0
2
3
3
7
0
3
3
7
0
+6
+3
+4
+7
+6
+2
52
【範例】
6
0
3
11
1
4
2
2
written by Wei-ShenLai
A-1
0
1
2
0
0
6
3
1
4
0
∞
2
11
2
0
A0
0
1
2
A1
0
1
2
A2
0
1
2
0
0
6
3
0
0
6
3
0
0
5
3
1
4
0
7
1
4
0
7
1
4
0
7
2
11
2
0
2
6
2
0
2
6
2
0
+6
+3
+4
+7
+6
+2
53
6-5-3 遞移封閉性(Transitive Closure)
 我們除了關心單點對全部頂點(Single Source All Destination)的最短路徑及所
有頂點兩兩之間的最短距離(All Pars Shortest Paths)外,另一個值得關心的
主題是如何才能判斷圖形G 中任意兩個頂點i 及j ,是否存在一條路徑。所謂遞
移封閉性(Transitive Closure),就是建立一個路徑矩陣(path matrix)P,從這
個矩陣中可以輕易判斷圖形G 中的任意兩個頂點間i 及j是否存在從i 到j 的路徑。
 在路徑矩陣中只0 與1 兩個值,若P i j=0 表示i 與j 之間不存在任何一條路徑,
若Pi,j=1 表示i 與j 兩個頂點間有路徑存在,且路徑長度大於等於1 。
 要建立路徑矩陣的步驟有:
先求得A1,A2,A3,A4...An ,其中An(aij)表示圖形頂點i 與j 間存在長度為n 的路徑
總數。
 將矩陣A1,A2,A3,A4...An全部相加,即令B=A1,A2,A3,A4...An 。
 令B 矩陣中所有元素大於0 的為1 ,可以得到元素值只有0 與1 的矩陣A+,我
們稱此矩陣為圖形G ,長度為n的Transitive Closure A+。
 Warshall 演算法
 for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
 A[i,j]=A[i,j] || (A[i,k] && A[k,j])
written by Wei-ShenLai
54
【範例:6 . 5 . 3 】
 求下圖長度為4 的Transitive Closure A+ 矩陣。
1
2
4
3
written by Wei-ShenLai
A
0
1
2
3
4
1
0
1
0
1
2
0
0
1
0
3
1
1
0
1
4
0
0
1
0
A1 1
2
3
4
A3 1
2
3
4
1
1
0
1
1
1
1
1
1
2
1
1
1
1
3
1
1
1
1
0
&& 0
&& 1
&& 0
2
0
0
1
0
3
1
1
0
1
4
0
0
1
0
4
1
1
1
1
A2 1
2
3
4
A4 1
2
3
4
1
1
1
1
1
1
1
1
1
2
1
1
1
1
3
1
1
1
1
4
1
1
1
1
0
2
0
0
1
0
3
1
1
1
1
4
0
0
1
0
&& 1
&& 1
&& 0
&& 1
&& 1
&& 1
&& 1
&& 1
&& 1
55
【範例】
0
1
A-1
0
1
2
3
4
0
0
0
0
0
0
2
1
1
0
0
0
0
3
2
0
1
0
0
1
written by Wei-ShenLai
3
0
0
1
0
0
4
4
0
0
0
1
0
A1
0
1
2
3
4
0
0
0
0
0
0
1
1
0
0
0
0
2
0
1
0
0
1
3
0
0
1
0
0
4
0
0
0
1
0
A1
0
1
2
3
4
0
0
0
0
0
0
1
1
0
0
0
0
2
1
1
0
0
1
3
0
0
1
0
0
4
0
0
0
1
0
A2
0
1
2
3
4
0
0
0
0
0
0
1
1
0
0
0
0
2
1
1
0
0
1
3
1
1
1
0
1
4
0
0
0
1
0
&&0
&&0
&&0
&&0
&&1
&&0
&&0
&&0
&&1
A3
0
1
2
3
4
0
0
0
0
0
0
1
1
0
0
0
0
2
1
1
0
0
1
3
1
1
1
0
1
4
1
1
1
1
1
A4
0
1
2
3
4
0
0
0
0
0
0
1
1
0
0
0
0
2
1
1
1
1
1
3
1
1
1
1
1
4
1
1
1
1
1
&&1
&&1
&&1
&&1
&&1
&&1
&&1
&&1
&&1
&&0
&&1
56
6-6 AOV 網路與拓樸排序
 網路圖形常被應用在規劃大型專案。通常在計劃一個專案時,會將
其細分成數個小計劃,這些小計劃通常有先後順序的關係。有些工
作可以同步進行,有些則有強制性的先後順序關係,如果能將這些
小計劃以圖形中的節點表示,我們就稱這類用圖形頂點來代表一項
工作的網路為頂點工作網(Activity On Vertex Network ,簡稱
AOV 網路)。也就是說專案若能以AOV網路來表示,那麼在工程進
度的管理與追蹤上就會變得更具效率。
written by Wei-ShenLai
57
6-6-1 AOV 網路基本定義
 以圖形嚴謹的定義來說,AOV網路就是一種有向圖形,在這個有向圖形中的每一個節點代表一
項工作或必須執行的動作,而那些有方向性的邊則代表了工作與工作之間存在的先後關係順序。
也就是說,Vi →Vj表示必須處理先完Vi的工作,才可以進行Vj的工作。
 舉個例子來說吧,要完成地下化高速鐵路這個大工程,可以把幾個重要且必須先行完成的細項工
作列出來,再把可以同時進行的工作列出來,依重要性及先後順序的關係畫成圖形:
土地開工
預算審核
土地取得
公開招標
軌道工程
機電工程
站區開發
車體結構
通車
 專有名詞:
 先行者:若頂點Vi 的工作必須先完成後,才能進行Vj 頂點的工作,則稱Vi為Vj的「先行
者」。
 拓樸排序與拓樸序列:如果在AOV 網路中,具有部份次序的關係(即有某幾個頂點為先行
者),拓樸排序的功能就是將這些部份次序(Partial Order)的關係,轉換成線性次序(Linear
Order)的關係。例如i是j的先行者,在線性次序中, i 仍排在j 的前面,具有這種特性的線
性次序就稱為拓樸序列(Topological Order)。
 底下我們為拓樸排序與拓樸序列作一摘要性的說明:
 產生拓樸序列的必須存在的條件是一個非循環圖形,由於AOV網路代表各項小工作的先後完成順
序圖,所以沒有循環的問題,也就是說AOV 網路經過拓樸排序後可以產生有線性次序關係拓樸序
列。
 在一個AOV 網路經過拓樸排序後所產生的拓樸序列可能有一個以上,亦即拓樸序列並不是唯一的。
written by Wei-ShenLai
58
6-6-2 拓樸排序探討
 拓樸排序的步驟
 步驟1 尋找圖形
中任何一個沒有
先行者的頂點。 A
 步驟2 輸出此頂
點,並將此頂點
的所有邊刪除。
 步驟3 重複上兩
個步驟處理所有
頂點。
 我們以下例來為各位
說明。
B
C
E
D
C
F
K
D
F
J
G
H
B
J
I
H
A
I
ABEGCFH
C
E
D
D
F
K
K
J
G
K
H
ABEG
I
J
I
ABEGCFHDI
K
J
B
A
C
E
D
ABEGCFHDIJ
F
J
G
H
written by Wei-ShenLai
I
K
K
ABEGCFHDIJK
59
【AOV練習】
C8
C1
C10
C3
C7
C2
C4
C9
C5
C6
C11
C12
C13
C14
C15
C1,C2,C4,C5,C3,C6,C8,C7,C10,C13,C12,C14,C15,C11,C9。
C4,C5,C2,C1,C6,C3,C8,C15,C7,C9,C10,C11,C12,C13,C14。
written by Wei-ShenLai
60
6-6-3 AOE 網路和臨界路徑(critical path)
 所謂AOE是指事件(event)的行動(action)在邊上之有向圖形。其中
的頂點做為各「進入邊事件」(incident in edge)的匯集點,當所有
「進入邊事件」的行動全部完成後,才可以開始「外出邊事件」
(incident out edge)的行動。
 AOE 完成所需的時間是由一條或數條的臨界路徑(critical path)所
控制。所謂臨界路徑(critical path)就是AOE 有向圖形從源頭
(source)頂點到目的(destination)頂點間所需花費時間最長的一條
有方向性的路徑。
想縮短整個AOE 完成的花費時間, 必須設法縮短臨界路徑各邊行動
所需花費的時間。
written by Wei-ShenLai
61
臨界路徑法
 臨界路徑法(Critical Path Method, CPM)前,我們先看看一些相
關定義。
最早時間(earlest time):TE
頂點的最早時間為該頂點最早可以開始其外出邊事件(incident out edge)
的時間,它必須由最慢完成的進入邊事件所控制,我們用TE 表示。
最晚時間(latest time):TL
頂點的最晚時間為該頂點最慢可以開始其外出邊事件(incident out edge)
而不會影響整個AOE 網路完成的時間。它是由外出邊事件(incident
out edge)中最早要求開始者所控制。我們以TL 表示。
臨界頂點(critical vertex)
頂點的TE=TL ,我們就稱它為臨界頂點。從源頭頂點到目的頂點的各
個臨界頂點可以構成一條或數條的有向臨界路徑。只要控制好臨界路徑
所花費的時間,就不會Delay工作進度。如果集中火力縮短臨界路徑所
需花費的時間, 就可以加速整個計劃完成的速度。
written by Wei-ShenLai
62
【AOE】
TL=6
TE=5
V2
TL=0 a1=5
TE=0
V1
a2=4
TL=17
TE=16
a4=3 TL=9
TE=8a7=8
TL=7
a =2
TE=4 5
V5
V8
a6=7
a11=2
V6
TE最大值
TL最小值
臨界路徑:V1→V4→V6→V8→V9→V10
written by Wei-ShenLai
TL=20
TE=20
V9
a9=5
TL=13
TE=13
TL=6
TE=6
V4
a10=3
TL=18
TE=18
a8=7
V3
a3=6
V7
TL=25
TE=25
a12=5 V
10
TE
TL
作業
a1
a2
a3
a4
a5
a6
a7
a8
a9
a10
a11
a12
1
2
3
4
5
6
7
8
9
10
0
0
5
6
4
7
6
6
8
9
13
13
16
17
18
18
20
20
25
25
early late
late-early
頭TE 尾TL-ai
0
1
1
0
3
3
0
0
0
5
6
1
4
7
3
6
6
0
8
9
1
8
11
3
13
13
0
16
17
1
18
18
0
20
20
0
63
【練習AOE】
TE=6
TL=6
TE=0
TL=0
V1
a0=6
V0 a1=4
TE=16
TL=16
TE=7
a3=1 TL=7
TE=4
TL=6 a4=1
V4
V6
a6=9
a7=7
V2
a2=5
TE=5
TL=8
V3
V7
TE=7
TL=10
a5=2
V5
a8=4
TE最大值
TL最小值
臨界路徑:V0→V1→V4→V6→V8
臨界路徑:V0→V1→V4→V7→V8
written by Wei-ShenLai
a9=2
TE=14
TL=14
a10=4
TE=18
TL=18
V8
TE
TL
作業
a0
a1
a2
a3
a4
a5
a6
a7
a8
a9
a10
0
1
2
3
4
5
6
7
8
0
0
6
6
4
6
5
8
7
7
7
10
16
16
14 18
14 18
early late late-early
頭TE 尾TL
0
0
0
0
2
2
0
3
3
6
6
0
4
6
2
5
8
3
7
7
0
7
7
0
7
10
3
16
16
0
14
14
0
64