770 likes | 1.01k Views
第六章 圖形結構. 課前指引 樹狀結構的最大不同是描述節點與節點之間「層次」的關係,但是圖形結構卻是討論兩個頂點之間「相連與否」的關係。圖形除了被活用在資料結構中最短路徑搜尋、拓樸排序外,還能應用在系統分析中以時間為評核標準的計劃評核術 (Performance Evaluation and Review Technique, PERT) ,又或者像一般生活中的「 IC 板設計」、「交通網路規劃」等都可以看做是圖形的應用。. 章節大綱. 6-1 圖形簡介. 6-5 圖形最短路徑. 6-2 圖形的資料表示法. 6-6 AOV 網路與拓樸排序.
E N D
第六章 圖形結構 課前指引 樹狀結構的最大不同是描述節點與節點之間「層次」的關係,但是圖形結構卻是討論兩個頂點之間「相連與否」的關係。圖形除了被活用在資料結構中最短路徑搜尋、拓樸排序外,還能應用在系統分析中以時間為評核標準的計劃評核術(Performance Evaluation and Review Technique, PERT),又或者像一般生活中的「IC板設計」、「交通網路規劃」等都可以看做是圖形的應用。
章節大綱 6-1 圖形簡介 6-5 圖形最短路徑 6-2 圖形的資料表示法 6-6 AOV網路與拓樸排序 6-3 圖形的走訪 6-7 AOE網路 6-4 擴張樹 備註:可依進度點選小節
6-1 圖形簡介 • 圖形的定義 • 圖形是由「頂點」和「邊」所組成的集合,通常用G=(V,E)來表示,其中V是所有頂點所成的集合,而E代表所有邊所成的集合。 • 圖形的種類有兩種:一是無向圖形,一是有向圖形,無向圖形以(V1,V2)表示,有向圖形則以<V1,V2>表示其邊線。
6-1 圖形簡介 • 無向圖形 • 是一種具備同邊的兩個頂點沒有次序關係,例如(V1,V2)與(V2,V1)是代表相同的邊。如下圖所示: V={A,B,C,D,E} E={(A,B),(A,E),(B,C),(B,D),(C,D),(C,E),(D,E)}
6-1 圖形簡介 • 無向圖形的重要術語介紹: • 完整圖形:在「無向圖形」中,N個頂點正好有N(N-1)/2條邊,則稱為「完整圖形」。如下圖所示: • 路徑(Path):對於從頂點Vi到頂點Vj的一條路徑,是指由所經過頂點所成的連續數列,如圖G中,V1到V5的路徑有{(V1,V2)、(V2, V5)}及{((V1,V2)、(V2,V3)、(V3,V4)、(V4,V5))等等。
6-1 圖形簡介 • 簡單路徑(Simple Path):除了起點和終點可能相同外,其他經過的頂點都不同,在圖G中,(V1,V2)、(V2,V3)、(V3,V1)、(V1,V5)不是一條簡單路徑。 • 路徑長度(Path Length):是指路徑上所包含邊的數目,在圖G中,(V1,V2),(V2,V3),(V3,V4),(V4,V5),是一條路徑,其長度為4,且為一簡單路徑。 • 循環(Cycle):起始頂點及終止頂點為同一個點的簡單路徑稱為循環。如上圖G,{(V1,V2),(V2,V4),(V4,V5),(V5,V3) ,(V3,V1)}起點及終點都是A,所以是一個循環。
6-1 圖形簡介 • 依附(Incident):如果Vi與Vj相鄰,我們則稱(Vi,Vj)這個邊依附於頂點Vi及頂點Vj,或者依附於頂點V2的邊有(V1,V2)、(V2,V4)、(V2,V5) 、(V2,V3)。 • 子圖(Subgraph):當我們稱G’為G的子圖時,必定存在V(G’) V(G)與E(G’) E(G),如下圖是上圖G的子圖。
6-1 圖形簡介 • 相鄰(Adjacent):如果(Vi,Vj)是E(G)中的一邊,則稱Vi與Vj相鄰。 • 相連單元(Connected Component):在無向圖形中,相連在一起的最大子圖(Subgraph),如圖G有2個相連單元。 • 分支度:在無向圖形中,一個頂點所擁有邊的總數為分支度。如上頁圖G,頂點1的分支度為4。
6-1 圖形簡介 • 有向圖形 • 是一種每一個邊都可使用有序對<V1,V2>來表示,並且<V1,V2>與<V2,V1>是表示兩個方向不同的邊,而所謂<V1,V2>,是指V1為尾端指向為頭部的V2。如下圖所示: V={A,B,C,D,E} E={<A,B>,<B,C>,<C,D>,<C,E>,<E,D>,<D,B>}
6-1 圖形簡介 • 有向圖形的相關定義介紹: • 完整圖形(Complete Graph):具有n個頂點且恰好有n*(n-1)個邊的有向圖形,如下圖所示: • 路徑(Path):有向圖形中從頂點Vp到頂點Vq的路徑是指一串由頂點所組成的連續有向序列。
6-1 圖形簡介 • 強連接(Strongly Connected):有向圖形中,如果每個相異的成對頂點Vi,Vj有直接路徑,同時,有另一條路徑從Vj到Vi,則稱此圖為強連接。如下圖: • 強連接單元(Strongly Connected Component):有向圖形中構成強連接的最大子圖,在下圖(a)中是強連接,但(b)就不是。
6-1 圖形簡介 • 出分支度(Out-degree):是指有向圖形中,以頂點V為箭尾的邊數目。 • 入分支度(In-degree):是指有向圖形中,以頂點V為箭頭的邊數目,如下圖中V4的入分支度為1,出分支度為0,V2的入分支度為4,出分支度為1 。
6-2 圖形的資料表示法 • 相鄰矩陣法 • 圖形A有n個頂點,以n*n的二維矩陣列表示。此矩陣的定義如下: 對於一個圖形G=(V,E),假設有n個頂點,n≧1,則可以將n個頂點的圖形,利用一個n×n二維矩陣來表示,其中假如A(i,j)=1,則表示圖形中有一條邊(Vi,Vj)存在。反之,A(i,j)=0,則沒有一條邊(Vi,Vj)存在。
1.對無向圖形而言,相鄰矩陣一定是對稱的,而且對角線一定為0。有向圖形則不一定是如此。1.對無向圖形而言,相鄰矩陣一定是對稱的,而且對角線一定為0。有向圖形則不一定是如此。 2.在無向圖形中,任一節點i的分支度為 ,就是第i列 所有元素的和。在有向圖中,節點i的出分支度為 ,就是第i列所有元素的和,而入分支度為 ,就是第j行所有元素的和。 3.用相鄰矩陣法表示圖形共需要n2空間,由於無向圖形的相鄰矩陣一定是具有對稱關係,所以扣除對角線全部為零外,僅需儲存上三角形或下三角形的資料即可,因此僅需n(n-1)/2空間。 6-2 圖形的資料表示法 • 相關特性說明如下:
6-2 圖形的資料表示法 • 範例 • 請以相鄰矩陣表示右列無向圖: • 由於上圖共有5個頂點,故使用5*5的二維陣列存放圖形。在上圖中,先找和①相鄰的頂點有那些,把和①相鄰的頂點座標填入1。 • 跟頂點1相鄰的有頂點2及頂點5,所以完成下表:
6-2 圖形的資料表示法 • 其他頂點依此類推可以得到相鄰矩陣: • 對於有向圖形,則不一定是對稱矩陣。其中節點i的出分支度為 ,就是第i列所有元素1的和,而 入分支度為 ,就是第j行所有元素1的和。例如下列有向圖的相鄰矩陣法:
6-2 圖形的資料表示法 • 範例 6.2.1 • 假設有一無向圖形各邊的起點值及終點值如下陣列: • 試設計一Java程式來輸出此圖形的相鄰矩陣。 int[][]data={{1,2},{2,1},{1,5},{5,1},{2,3},{3,2},{2,4},{4,2},{3,4},{4,3},{3,5},{5,3},{4,5},{5,4}};
6-2 圖形的資料表示法 • 範例 6.2,2 • 請以相鄰矩陣表示下列有向圖。 解答:和無向圖形的作法一樣,找出相鄰的點並把邊連接的兩個頂點矩陣值填入1。不同的是橫列座標為出發點,直行座標為終點。如下表所示:
6-2 圖形的資料表示法 • 範例 6.2.3 • 假設有一有向圖形各邊的起點值及終點值如下陣列: • 試輸出此圖形的相鄰矩陣。 int data[7][2]={{1,2},{2,1},{2,3},{2,4},{4,3}};
6-2 圖形的資料表示法 • 相鄰串列法 • 這種表示法就是將一個n列的相鄰矩陣,表示成n個鏈結串列,這種作法和相鄰矩陣相比較節省空間,如計算所有頂點的分支度時,其時間複雜度為O(n+e),缺點是圖形新邊的加入或刪除會更動到相關的串列鏈結,較為麻煩費時。 • 首先將圖形的n個頂點形n個串列首,每個串列中的節點表示它們和首節點之間有邊相連。每個節點資料結構如下:
6-2 圖形的資料表示法 • 範例 • 討論下面兩個圖如何使用相鄰串列表示: • 首先來看(a)圖,因為5個頂點使用5個串列首,V1串列代表頂點1,與頂點1相鄰的頂點有2及5,依此類推。
6-2 圖形的資料表示法 • 範例 6.2.4 • 請設計一Java程式,使用陣列儲存圖形的邊,並利用相鄰串列法來輸出鄰接節點的內容。 int Data[][]={ {1,2},{2,1},{1,5},{5,1},{2,3},{3,2},{2,4},{4,2},{3,4},{4,3},{3,5},{5,3},{4,5},{5,4} };
6-2 圖形的資料表示法 • 相鄰複合串列法 • 相鄰多元串列的節點是存放邊線的資料,其結構如下: • 其中相關特性說明如下: M:是記錄該邊是否被找過的一個位元之欄位。 V1及V2:是所記錄的邊的起點與終點。 LINK1:在尚有其它頂點與V1相連的情況下,此欄位會指向下一個與V1相連的邊節點,如果已經沒有任何頂點與V1相連時,則指向NULL。 LINK2:在尚有其它頂點與V2相連的情況下,此欄位會指向下一個與V2相連的邊節點,如果已經沒有任何頂點與V2相連時,則指向NULL。
解答 其表示法為: 6-2 圖形的資料表示法 • 範例 6.2.5 • 試求出右圖的相鄰複合串列表示法。 由左圖,我們可以得知: 頂點1(V1):N1N2N3 頂點2(V2):N1N4N5 頂點3(V3):N2N4N6 頂點4(V4):N3N5N6
6-2 圖形的資料表示法 • 索引表格法 • 是一種用一維陣列來依序儲存與各頂點相鄰的所有頂點,並建立索引表格,來記錄各頂點在此一維陣列中第一個與該頂點相鄰的位置。將以下圖來說明索引表格法的實例。 • 則索引表格法的表示外觀為:
6-2 圖形的資料表示法 • 範例 6.2.6 • 下圖為尤拉七橋問題的圖示法,A,B,C,D為四島,1,2,3,4,5,6,7為七橋,今欲以不同之資料結構描述此圖,試說明三種不同的表示法。
解答 根據複線圖的定義,Euler七橋問題是一種複線圖,它並不是 圖。如果要以不同表示法來實作圖形的資料結構,必須先將上 述的複線圖分解成如下的兩個圖形: 6-2 圖形的資料表示法
6-2 圖形的資料表示法 • 相鄰矩陣、相鄰串列及索引表格法(1/3) • 相鄰矩陣(Adjacency Matrix) • 令圖形G=(V,E)共有n個頂點,我們以n*n的二維矩陣來表示點與點之間是否相鄰。其中 aij=0表示頂點i及j頂點沒有相鄰的邊 aij=1表示頂點i及j頂點有相鄰的邊
6-2 圖形的資料表示法 • 相鄰矩陣、相鄰串列及索引表格法(2/3) • 相鄰串列法(Adjacency Lists)
6-2 圖形的資料表示法 • 相鄰矩陣、相鄰串列及索引表格法(3/3) • 索引表格法(Indexed Table) • 是一種用一個一維陣列,來依序儲存與各頂點相鄰的所有頂點,並建立索引表格,來記錄各頂點在此一維陣列中第一個與該頂點相鄰的位置。
6-3 圖形的走訪 • 先深後廣法 • 這種圖形追蹤方法結合了遞迴及堆疊兩種資料結構的技巧,由於此方法會造成無窮迴路,所以必須加入一個變數,判斷該點是否已經走訪完畢。底下以下圖來看看這個方法的走訪過程: • 步驟1 • 以頂點1為起點,將相鄰的頂點2及頂點5放入堆疊。
6-3 圖形的走訪 • 步驟2 • 取出頂點2,將與頂點2相鄰且未拜訪過的頂點3及頂點4放入堆疊。 • 步驟3 • 取出頂點3,將與頂點3相鄰且未拜訪過的頂點4及頂點5放入堆疊。 • 步驟4 • 取出頂點4,將與頂點4相鄰且未拜訪過的頂點5放入堆疊。
6-3 圖形的走訪 • 步驟5 • 取出頂點5,將與頂點5相鄰且未拜訪過的頂點放入堆疊,各位可以發現與⑤相鄰的頂點全部被拜訪過,所以無需再放入堆疊。 • 步驟6 • 將堆疊內的值取出並判斷是否已經走訪過了,直到堆疊內無節點可走訪為止。 • 故先深後廣的走訪順序為:頂點1、頂點2、頂點3、頂點4、頂點5。
6-3 圖形的走訪 • 範例 6.3.1 • 請將上圖的先深後廣搜尋法,以Java程式實作,其中圖形陣列如下: int data[20][2]={{1,2},{2,1},{1,3},{3,1}, {2,4},{4,2},{2,5},{5,2}, {3,6},{6,3},{3,7},{7,3}, {4,5},{5,4},{6,7},{7,6}, {5,8},{8,5},{6,8},{8,6}};
6-3 圖形的走訪 • 先廣後深搜尋法 • 走訪方式則是以佇列及遞迴技巧來走訪,也是從圖形的某一頂點開始走訪,被拜訪過的頂點就做上已拜訪的記號。 • 底下以下圖來看看BFS的走訪過程: • 步驟1 • 以頂點1為起點,與頂點1相鄰且未拜訪過的頂點2及頂點5放入佇列。
6-3 圖形的走訪 • 步驟2 • 取出頂點2,將與頂點2相鄰且未拜訪過的頂點3及頂點4放入佇列。 • 步驟3 • 取出頂點5,將與頂點5相鄰且未拜訪過的頂點3及頂點4放入佇列。 • 步驟4 • 取出頂點3,將與頂點3相鄰且未拜訪過的頂點4放入佇列。
6-3 圖形的走訪 • 步驟5 • 取出頂點4,將與頂點4相鄰且未拜訪過的頂點放入佇列中,各位可以發現與頂點4相鄰的頂點全部被拜訪過,所以無需再放入佇列中。 • 步驟6 • 將佇列內的值取出並判斷是否已經走訪過了,直到佇列內無節點可走訪為止。 • 先廣後深的走訪順序為:頂點1、頂點2、頂點5、頂點3、頂點4。
6-3 圖形的走訪 • 範例 6.3.2 • 請將上圖的先廣後深搜尋法,以Java程式實作。先廣後深的程式寫法與先深後廣的寫法類似,需注意的使用技巧不同,先廣後深必須使用佇列的技巧。其中圖形陣列如下: int data[20][2]={{1,2},{2,1},{1,3},{3,1}, {2,4},{4,2},{2,5},{5,2}, {3,6},{6,3},{3,7},{7,3}, {4,5},{5,4},{6,7},{7,6}, {5,8},{8,5},{6,8},{8,6}};
6-4 擴張樹 • 擴張樹 • 又稱「花費樹」或「值樹」,當一個圖形連通時,則使用DFS或BFS必能拜訪圖形中所有的頂點,且G=(V,E)的所有邊可分成兩個集合:T和B(T為搜尋時所經過的所有邊,而B為其餘未被經過的邊)。if S=(V,T)為G中的擴張樹(Spanning Tree),具有以下三項性質: 1.E=T+B 2.加入B中的任一邊到S中,則會產生循環(Cycle)。 3.V中的任何2頂點Vi、Vj在S中存在唯一的一條簡單路徑。
6-4 擴張樹 • DFS擴張樹及BFS擴張樹 • 一棵擴張樹也可以利用先深後廣搜尋法(DFS)與先廣後深搜尋法(BFS)來產生,所得到的擴張樹則稱為縱向擴張樹(DFS擴張樹)或橫向擴張樹(BFS擴張樹)。 • 練習求出下圖的DFS擴張樹及BFS擴張樹:
6-4 擴張樹 • 依擴張樹的定義,可以得到下列幾顆擴張樹: • 由上圖我們可以得知,一個圖形通常具有不只一顆擴張樹。上圖的先深後廣擴張樹為,如下圖(a),先廣後深擴張樹則為,如下圖(b): (b) (a)
6-4 擴張樹 • 最小花費擴張樹 • 假設在樹的邊加上一個權重(weight)值,這種圖形就成為「加權圖形(Weighted Graph)」。如果這個權重值代表兩個頂點間的距離(distance)或成本(Cost),這類圖形就稱為網路(Network)。如下圖所示:
6-4 擴張樹 • 假如想知道從某個點到另一個點間的路徑成本,例如由頂點1到頂點5有(1+2+3)、(1+6+4)及5這三個路徑成本,而「最小成本擴張樹(Minimum Cost Spanning Tree)」則是路徑成本為5的擴張樹。請看下圖說明:
6-4 擴張樹 • Kruskal演算法 • Kruskal演算法是將各邊線依權值大小由小到大排列,接著從權值最低的邊線開始架構最小成本擴張樹,如果加入的邊線會造成迴路則捨棄不用,直到加入了n-1個邊線為止。 • 如何以K氏法得到範例下圖中最小成本擴張樹:
6-4 擴張樹 • 步驟1 • 把所有邊線的成本列出並由小到大排序: • 步驟2 • 選擇成本最低的一條邊線作為架構最小成本擴張樹的起點。
6-4 擴張樹 • 步驟3 • 依步驟1所建立的表格,依序加入邊線。 • 步驟4 • C─D加入會形成迴路,所以直接跳過。 • 完成圖
6-4 擴張樹 • 範例 6.4.1 • 以下將利用一個二維陣列儲存並排序K氏法的成本表,試設計一Java程式來求取最小成本花費樹,二維陣列如下: int data[10][3]={{1,2,6},{1,6,12},{1,5,10},{2,3,3}, {2,4,5},{2,6,8},{3,4,7},{4,6,11}, {4,5,9},{5,6,16}};