Tài liệu môn học - Application of Algo. chapter06 tài liệu, giáo án, bài giảng , luận văn, luận án, đồ án, bài tập lớn v...
Thuật tốn đồ thị Ứng dụng Khoa Cơng Nghệ Thông Tin, Trường Đại Học Thủy Lợi Ngày tháng năm 2017 / 50 Đồ thị khái niệm liên quan Nhiều đối tượng sống hàng ngày mơ hình hóa đồ thị Internet, mạng xã hội (facebook), mạng giao thông, mạng sinh học, Một đồ thị G đối tượng toán học bao gồm tập xác định, G = (V , E ) V tập đỉnh E tập cạnh kết nối đỉnh Đồ thị có nhiều kiểu: có hướng, vô hướng, đa đồ thị, / 50 Những định nghĩa Một đồ thị vô hướng G = (V , E ) V = (v1 , v2 , , ) tập đỉnh nút E ⊆ V × V tập cạnh (cũng gọi cạnh vô hướng) E tập cặp khơng có thứ tự cho u = v ∈ V (u, v ) ∈ E (v , u) ∈ E / 50 Những định nghĩa Một đồ thị có hướng G = (V , E ) V = (v1 , v2 , , ) tập đỉnh nút E ⊆ V × V tập cung (cũng gọi cạnh có hướng) E tập cặp có thứ tự cho u = v ∈ V / 50 Đa đồ thị Một đa thị vơ hướng (có hướng) đồ thị có nhiều cạnh (cung), tức cạnh (cung) có hai đỉnh đầu cuối Hai đỉnh kết nối nhiều cạnh (cung) / 50 Những định nghĩa Cho đồ thị G = (V , E ), với (u, v ) ∈ E , nói u v hai cạnh kề Cho đồ thị vô hướng G = (V , E ) bậc đỉnh v số lượng cạnh nối với nó: deg (v ) = {(u, v ) | (u, v ) ∈ E } Cho đồ thị có hướng G = (V , E ) Một cung đến đỉnh cung vào Một cung đỉnh cung từ indegree (outdegree) đỉnh v số lượng cung đến (đi) deg + (v ) = {(v , u) | (v , u) ∈ E }, deg − (v ) = {(u, v ) | (u, v ) ∈ E } / 50 Những định nghĩa Theorem Cho đồ thị vô hướng G = (V , E ), có × |E | = deg (v ) v ∈V Theorem Cho đồ thị có hướng G = (V , E ), có deg − (v ) = |E | deg + (v ) = v ∈V v ∈V / 50 Định nghĩa - Đường đi, Chu trình Cho đồ thị G = (V , E ), đường từ đỉnh u tới đỉnh v G chuỗi u = x0 , x1 , , xk = v (xi , xi+1 ) ∈ E , ∀i = 0, 1, , k − u: điểm (nút) bắt đầu v : điểm kết thúc k chiều dài đường (tức là, tổng số cạnh đường đi) Một chu trình đường cho nút đầu nút cuối giống Một đường (chu trình) gọi đơn giản khơng chứa cạnh (cung) lặp Một đường (chu trình) gọi không chứa nút lặp / 50 Sự liên thông Cho đồ thị vô hướng G = (V , E ) G gọi liên thông với cặp (u, v ) (u, v ∈ V ), tồn đường từ u đến v G Cho đồ thị có hướng G = (V , E ), G gọi liên thông yếu đồ thị vô hướng tương ứng G (bằng cách bỏ hướng cung nó) liên thơng liên thơng mạnh với cặp (u, v ) (u, v ∈ V ), tồn đường từ u đến v G Cho đồ thị vô hướng G = (V , E ) cạnh e gọi cầu loại bỏ e khỏi G làm tăng số lượng thành phần liên thông G đỉnh v gọi điểm khớp loại bỏ khỏi G làm tăng số lượng thành phần liên thông G / 50 Sự liên thông Theorem Một đồ thị vơ hướng liên thơng G trở thành có hướng (mỗi cạnh G có hướng) để đạt đồ thị liên thông mạnh cạnh G nằm chu trình 10 / 50 Chu trình Euler Hamilton Theorem Một đồ thị vô hướng liên thông G = (V , E ) Euler đỉnh G có bậc chẵn 36 / 50 Chu trình Euler Hamilton G liên thơng bậc nút chẵn Do đó, bậc nút lớn ⇒ tồn chu trình C = v1 , v2 , , vk , v1 G Loại bỏ tất cạnh C , thu đồ thị G mà chia thành thành phần liên thông G1 , , Gq Mỗi Gi liên thông bậc nút Gi chẵn ⇒, tồn chu trình Euler Ci Gi Chúng ta xây dựng chu trình Euler G sau: Bắt đầu từ v1 , di chuyển dọc theo chu trình Euler thành phần liên thông chứa v1 kết thúc v1 Đi đến v2 Nếu thành phần liên thông chứa v2 mà chưa thăm, dọc chu trình Euler thành phần liên thơng từ v2 kết thúc v2 Đi đến v3 Nếu thành phần liên thông chứa v3 mà chưa thăm, dọc chu trình Euler thành phần liên thông từ v3 kết thúc v3 Quay trở lại v1 37 / 50 Thuật tốn để tìm chu trình Euler Algorithm 8: EULER-CYCLE(G ) Stack S ← ; Stack CE ← ; u ← select a vertex of G V ; Push(S, u); while S = x ← Top(S); if G Adj[x] = then y ← select a vertex of G Adj[x]; Push(S, y ); Remove (x, y ) from G ; else x ← Pop(S); Push(CE , x); while CE = v ← Pop(CE ); output(v ); 38 / 50 Định lý Dirak Theorem (Dirak 1952) Một đồ thị vô hướng G = (V , E ) bậc đỉnh lớn |V2 | đồ thị Hamilton 39 / 50 Cây Cây bao trùm Một đồ thị vô hướng liên thơng khơng chứa chu trình Một bao trùm đồ thị vô hướng liên thông G = (V , E ) T = (V , F ) với F ⊆ E a Cây b Cây bao trùm (những cạnh in đậm) 40 / 50 Cây Theorem Cho đồ thị vô hướng T = (V , E ) Chúng ta có: Nếu T T khơng có chu trình bao gồm |V | − cạnh Nếu T chu trình bao gồm |V | − cạnh T liên thơng Nếu T liên thơng bao gồm |V | − cạnh cạnh T cầu Nếu T liên thông cạnh cầu với cặp u, v ∈ V , tồn đường T kết nối chúng Nếu với cặp u, v ∈ V tồn đường T kết nối chúng, T khơng chứa chu trình chu trình tạo thêm cạnh kết nối cặp nút 41 / 50 Cây bao trùm nhỏ (MST) Cho đồ thị vơ hướng có trọng số G = (V , E ), cạnh e ∈ E gắn với trọng số w (e) Trọng số bao trùm T định nghĩa w (T ) = w (e) e∈ET với ET tập cạnh T Tìm bao trùm G cho tổng trọng số cạnh nhỏ Theorem Với đồ thị G có trọng số phân biệt cạnh, MST T G thỏa mãn thuộc tính sau: Thuộc tính cut: với cut (X , X ) G , T phải chứa cạnh ngắn xun qua cut Thuộc tính chu trình: đặt C chu trình G , T khơng chứa cạnh dài C 42 / 50 Thuật toán Kruskal Algorithm 9: KRUSKAL(G = (V , E )) C ← tập cạnh G ; ET ← ∅; VT ← ∅; while |VT | < |V | (u, v ) ← cạnh ngắn C ; C ← C \ {(u, v )}; if ET ∪ {(u, v )} không tạo chu trình then ET ← ET ∪ {(u, v )}; VT ← VT ∪ {u, v }; return (VT , ET ); 43 / 50 Thuật toán Prim Algorithm 10: PRIM(G = (V , E )) s ← tập cạnh V ; S ← V \ {s}; VT ← {s}; ET ← ∅; foreach v ∈ V d(v ) ← w (s, v ); near (v ) ← s; while |VT | < |V | v ← argMinu∈S d(u); S ← S \ {v }; VT ← VT ∪ {v }; ET ← ET ∪ {(v , near (v ))}; foreach u ∈ S if d(u) > w (u, v ) then d(u) ← w (u, v ); near (u) ← v ; return (VT , ET ); 44 / 50 Bài toán đường ngắn Cho đồ thị G = (V , E ), cạnh e gắn với trọng số w (e) Bài tốn đường ngắn nguồn-đơn Tìm đường ngắn từ nút nguồn cho trước s tới tất nút khác G Bài tốn đường ngắn tất-cả-cặp-đỉnh Tìm đường ngắn cặp đỉnh u, v G 45 / 50 Thuật tốn Bellman-Ford Đồ thị khơng có chu trình âm Algorithm 11: Bellman-Ford(G = (V , E ), s) foreach v ∈ V d(v ) ← w (s, v ); p(v ) ← s; d(s) ← 0; foreach k = 1, , n − foreach v ∈ V \ {s} foreach u ∈ V if d(v ) > d(u) + w (u, v ) then d(v ) ← d(u) + w (u, v ); p(v ) ← u; 46 / 50 Bài toán đường ngắn đồ thị có hướng khơng chu trình (DAG) Cho đồ thị có hướng khơng chu trình (DAG) nút nguồn s ∈ V Tìm đường ngắn từ s đến tất nút khác G Algorithm 12: ShortestPathAlgoDAG(G = (V , E ), s) L ← Topological sort vertices of G ; foreach v ∈ V d(v ) ← w (s, v ); d(s) ← 0; foreach v ∈ L foreach u ∈ G Adj[v ] d(u) ← min(d(u), d(v ) + w (v , u)); 47 / 50 Thuật tốn Dijkstra Đồ thị khơng có cạnh trọng số âm Algorithm 13: Dijkstra(G = (V , E ), s) foreach x ∈ V d(x) ← w (s, x); pred(x) ← s; NonFixed ← V \ {s}; Fixed ← {s}; while NonFixed = ∅ (*get the vertex v of NonFixed such that d(v ) is minimal*); v ← argMinu∈NonFixed d(u); NonFixed ← NonFixed \ {v }; Fixed ← Fixed ∪ {v }; foreach x ∈ NonFixed if d(x) > d(v ) + w (v , x) then d(x) ← d(v ) + w (v , x); pred(x) ← v ; 48 / 50 Đường ngắn Tất-cả-cặp-đỉnh Thuật toán Floyd-Warshall Algorithm 14: Floyd-Warshall(G = (V , E )) foreach u ∈ V foreach v ∈ V d(u, v ) ← w (u, v ); p(u, v ) ← u; foreach z ∈ V foreach u ∈ V foreach v ∈ V if d(u, v ) > d(u, z) + d(z, v ) then d(u, v ) ← d(u, z) + d(z, v ); p(u, v ) ← p(z, v ); 49 / 50 Đường ngắn hai đỉnh rời Thuật toán Suurballe Algorithm 15: Suurballe(G , s, t) Input: G = (V , E , w ), s, t ∈ V Output: Tập cung Đường ngắn Cặp rời từ s đến t G Áp dụng thuật toán Dijkstra G ; P1 ← đường ngắn từ s đến t G ; foreach v ∈ V dG (s, v ) ← khoảng cách ngắn từ s đến v G ; foreach (u, v ) ∈ E w (u, v ) ← w (u, v ) − dG (s, v ) + dG (s, u); E ← {}; foreach arc (u, v ) ∈ E if (u, v ) ∈ P1 then if (v , u) ∈ / E then E ← E ∪ {(v , u)}; w (v , u) ← 0; else E ← E ∪ {(u, v )}; G ← (V , E , w ); Áp dụng thuật toán Dijkstra G ; P2 ← đường ngắn từ s đến t G ; P ← {(u, v ) | (u, v ) ∈ P1 ∧ (v , u) ∈ P2 ∨ (u, v ) ∈ P2 ∧ (v , u) ∈ P1 }; return tập cung P1 P2 không bao gồm P; 50 / 50 ... COMPUTE-CC(G ) foreach u ∈ G V u.color ← WHITE; foreach u ∈ G V if u.color = WHITE then C ← new set; DFS-CC(G , u, C ); output(C ); 26 / 50 Tính thành phần liên thơng Algorithm 6: DFS-CC(G ,... thành thành phần liên thông mạnh G 28 / 50 Kiểm tra liệu đồ thị cho trước có hai phía Gọi BFS từ vài đỉnh Tơ màu đỉnh bậc-chẵn "BLACK" đỉnh bậc-lẻ "WHITE" Nếu tồn đỉnh cho hai điểm đầu cuối có... kiếm theo chiều sâu (DFS) Algorithm 1: DFS-VISIT(G , u) t ← t + 1; u.d ← t; u.color ← GRAY; foreach v ∈ G Adj[u] if v color =WHITE then v p ← u; DFS-VISIT(G , v ); u.color ← BLACK; t ← t + 1;