Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 21 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
21
Dung lượng
186 KB
Nội dung
CÁCPHƯƠNGPHÁPTÌMKIẾMTRÊNĐỒTHỊ Một toán quan trọng lí thuyết đồthị toán duyệt tất đỉnh đến từ đỉnh xuất phát Vấn đề đưa toán liệt kê mà yêu cầu không bỏ sót hay lặp lại đỉnh Chính mà ta phải xây dựng thuật toán cho phép duyệt cách hệ thống đỉnh, thuật toán gọi thuật toán tìmkiếmđồthị (graph traversal) Ta quan tâm đến hai thuật toán nhất: thuật toán tìmkiếm theo chiều sâu thuật toán tìmkiếm theo chiều rộng Thuật toán tìmkiếm theo chiều sâu : a Thuật toán tìmkiếm theo chiều sâu: Ý tưởng: Tư tưởng thuật toán tìmkiếm theo chiều sâu (Depth-First Search - DFS) trình bày sau: Trước hết, dĩ nhiên đỉnh s đến từ s, tiếp theo, với cung (s, x) đồthị x đến từ s Với đỉnh x tất nhiên đỉnh y nối từ x đến từ s Điều gợi ý cho ta viết thủ tục đệ quy DFSVisit(u) mô tả việc duyệt từ đỉnh u cách thăm đỉnh u tiếp tục trình duyệt DFSVisit(v) với v đỉnh chưa thăm nối từ u Kĩ thuật đánh dấu sử dụng để tránh việc liệt kê lặp đỉnh: Khởi tạo avail[v]:=true, ∀v∈V, lần thăm đỉnh, ta đánh dấu đỉnh lại (avail[v]:=false) để bước duyệt đệ quy không duyệt lại đỉnh Thuật toán: procedure DFSVisit(u ∈ V); //Thuật toán tìmkiếm theo chiều sâu từ đỉnh u begin avail[u] := False; //avail[u] = False ⇔ u thăm Output ← u; //Liệt kê u for ∀v ∈ V:(u, v)∈ E //Duyệt đỉnh v chưa thăm nối từ u if avail[v] then DFSVisit(v); end; begin //Chương trình Input → Đồthị G for ∀v ∈ V avail[v] := True; //Đánh dấu đỉnh chưa thăm DFSVisit(s); end b Thuật toán tìmđường theo DFS: Bài toán tìmđường đi: Cho đồthị G=(V,E) hai đỉnh s, t ∈ V Nhắc lại định nghĩa đường đi: Một dãy đỉnh: P= (∀i: (pi-1, pi) ∈ E) gọi đường từ s tới t, đường gồm k+1 đỉnh p0 , p1, …, pk cạnh (p0, p1), (p1, p2), …,(pk-1, pk) Đỉnh s gọi đỉnh đầu đỉnh t gọi đỉnh cuối đường Nếu tồn đường từ s tới t, ta nói s đến t t đến từ s: s t Thuật toán: Để lưu lại đường từ đỉnh xuất phát s, thủ tục DFSVisit(u), trước gọi đệ quy DFSVisit(v) với v đỉnh chưa thăm nối từ u chưa đánh dấu), ta lưu lại vết đường từ u tới v cách đặt trace[v]:=u, tức trace[v] lưu lại đỉnh liền trước v đường từ s tới v Khi thuật toán DFS kết thúc, đường từ s tới t là: procedure DFSVisit(u∈V); //Thuật toán tìmkiếm theo chiều sâu từ đỉnh u begin avail[u] := False; //avail[u] = False ⇔ u thăm for ∀ v∈ V:(u, v)∈ E //Duyệt đỉnh v chưa thăm nối từ u if avail[v] then begin trace[v] := u; //Lưu vết đường đi, đỉnh liền trước v đường từ s tới v u DFSVisit(v); //Gọi đệ quy đểtìmkiếm theo chiều sâu từ đỉnh v end; end; begin / /Chương trình Input → Đồthị G, đỉnh xuất phát s, đỉnh đích t; for ∀v ∈ V avail[v] := True; //Đánh dấu đỉnh chưa thăm DFSVisit(s); if avail[t] then //s đến t «Truy theo vết từ t đểtìmđường từ s tới t»; end Có thể không cần mảng đánh dấu avail[1 … n] mà dùng mảng trace[1 … n] để đánh dấu: Khởi tạo phần tử mảng trace[1 … n] là: Trace[s]≠0 Trace[v]=0, ∀v≠s Khi điều kiện để đỉnh v chưa thăm trace[v] = 0, từ đỉnh u thăm đỉnh v, phép gán trace[v]= u kiêm công việc đánh dấu v thăm (trace[v] ≠ 0) Tính chất BFS Nếu ta xếp danh sách kề đỉnh theo thứ tự tăng dần thuật toán DFS trả đường có thứ tự từ điển nhỏ số tất đường từ s tới tới t c Thuật toán duyệt đồthị theo DFS Cài đặt ứng dụng thuật toán DFS để liệt kê đỉnh đến từ đỉnh Thuật toán DFS dùng để duyệt qua đỉnh cạnh đồthị viết sau: procedure DFSVisit(u∈V); //Thuật toán tìmkiếm theo chiều sâu từ đỉnh u begin Time := Time + 1; d[u] := Time; //Thời điểm duyệt đến u Output ← u; //Liệt kê u for ∀v∈V:(u, v) ∈E //Duyệt đỉnh v nối từ u if d[v] = then DFSVisit(v); //Nếu v chưa thăm, gọi đệ quy đểtìm // kiếm theo chiều sâu từ đỉnh v Time := Time + 1; f[u] := Time; //Thời điểm duyệt xong u end; begin //Chương trình Input → Đồthị G for ∀v∈V d[v] := 0; //Mọi đỉnh chưa duyệt đến Time := 0; for ∀v∈V if d[v] = then DFSVisit(v); end Thời gian thực giải thuật DFS đánh giá số lần gọi thủ tục DFSVisit (|V| lần) cộng với số lần thực vòng lặp for bên thủ tục DFSVisit Chính vậy: • Nếu đồthị biểu diễn danh sách kề danh sách liên thuộc, vòng lặp for bên thủ tục DFSVisit (xét tổng thể chương trình) duyệt qua tất cạnh đồthị (mỗi cạnh hai lần đồthị vô hướng, cạnh lần đồthị có hướng) Trong trường hợp này, thời gian thực giải thuật DFS Θ(|V| + |E|) • Nếu đồthị biểu diễn ma trận kề, vòng lặp for bên thủ tục DFSVisit phải duyệt qua tất đỉnh … n Trong trường hợp thời gian thực giải thuật DFS Θ(|V| + |V|2) = Θ(| V|2) • Nếu đồthị biểu diễn danh sách cạnh, vòng lặp for bên thủ tục DFSVisit phải duyệt qua tất danh sách cạnh lần thực thủ tục Trong trường hợp thời gian thực giải thuật DFS Θ(|V||E|) Thuật toán tìmkiếm theo chiều rộng: a Thuật toán tìmkiếm theo chiều rộng Ý tưởng: s u u s v v s s … Thăm trước tất đỉnh v s … Thăm sau tất đỉnh u Tư tưởng thuật toán tìmkiếm theo chiều rộng (Breadth-First Search – BFS) “lập lịch” duyệt đỉnh Việc thăm đỉnh lên lịch duyệt đỉnh nối từ cho thứ tự duyệt ưu tiên chiều rộng (đỉnh gần đỉnh xuất phát s duyệt trước) Đầu tiên ta thăm đỉnh s Việc thăm đỉnh s phát sinh thứ tự thăm đỉnh u1, u2, … nối từ s (những đỉnh gần s nhất) Tiếp theo ta thăm đỉnh u1, thăm đỉnh u1 lại phát sinh yêu cầu thăm đỉnh r1, r2, … nối từ u1 Nhưng rõ ràng đỉnh r “xa” s đỉnh u nên chúng thăm tất đỉnh u thăm Tức thứ tự duyệt đỉnh là: s, u1, u2, … , r1, r2, … Thuật toán tìmkiếm theo chiều rộng sử dụng danh sách để chứa đỉnh “chờ” thăm Tại bước, ta thăm đỉnh đầu danh sách, loại khỏi danh sách cho đỉnh chưa “xếp hàng” kề với xếp hàng thêm vào cuối danh sách Thuật toán kết thúc danh sách rỗng Vì nguyên tắc vào trước trước, danh sách chứa đỉnh chờ thăm tổ chức dạng hàng đợi (Queue): Nếu ta có Queue hàng đợi với thủ tục Push(r) để đẩy đỉnh r vào hàng đợi hàm Pop trả đỉnh lấy từ hàng đợi thuật toán BFS viết sau: Thuật toán: Queue := (s); //Khởi tạo hàng đợi gồm đỉnh s for ∀v∈V avail[v] := True; avail[s] := False; //Đánh dấu có đỉnh s xếp hàng repeat //Lặp tới hàng đợi rỗng u := Pop; //Lấy từ hàng đợi đỉnh u Output ← u; //Liệt kê u for ∀v∈V:avail[v] and (u, v) ∈ E //Xét đỉnh v kề u chưa //đẩy vào hàng đợi begin Push(v); //Đẩy v vào hàng đợi avail[v] := False; //Đánh dấu v xếp hàng end; until Queue = Ø; Thuật toán tìmđường theo BFS: Queue := (s); //Khởi tạo hàng đợi gồm đỉnh s for ∀v∈V avail[v] := True; avail[s] := False; //Đánh dấu có đỉnh s xếp hàng repeat //Lặp tới hàng đợi rỗng u := Pop; //Lấy từ hàng đợi đỉnh u for ∀v∈V:avail[v] and (u, v) ∈ E //Xét đỉnh v kề u chưa //đẩy vào hàng đợi begin trace[v] := u; //Lưu vết đường Push(v); //Đẩy v vào hàng đợi avail[v] := False; //Đánh dấu v xếp hàng end; until Queue = Ø; if avail[t] then //s tới t «Truy theo vết từ t đểtìmđường từ s tới t»; Tương tự thuật toán tìmkiếm theo chiều sâu, ta dùng mảng Trace[1 … n] kiêm chức đánh dấu Tính chất BFS Thuật toán BFS trả đường qua cạnh số tất đường từ s tới t Nếu ta xếp danh sách kề đỉnh theo thứ tự tăng dần có nhiều đường từ s tới t qua cạnh thuật toán BFS trả đường có thứ tự từ điển nhỏ số đường c Thuật toán duyệt đồthị theo BFS Tương tự thuật toán DFS, thực tế, thuật toán BFS dùng để xác định thứ tự đỉnh đồthị viết theo mô hình sau: procedure BFSVisit(s∈V); begin Queue := (s); //Khởi tạo hàng đợi gồm đỉnh s Time := Time + 1; d[s] := Time; //Duyệt đến đỉnh s repeat //Lặp tới hàng đợi rỗng u := Pop; //Lấy từ hàng đợi đỉnh u Time := Time+1; F[u]:=Time; //Ghi nhận thời điểm duyệt xong đỉnh u Output ← u; //Liệt kê u for ∀v∈V:(u, v) ∈E //Xét đỉnh v kề u if d[v] = then //Nếu v chưa duyệt đến begin Push(v); //Đẩy v vào hàng đợi Time := Time + 1; d[v] := Time; //Ghi nhận thời điểm duyệt đến đỉnh v end; until Queue = Ø; end; begin //Chương trình Input → Đồthị G; for ∀v∈V d[v] := 0; //Mọi đỉnh chưa duyệt đến Time := 0; for ∀v∈V if d[v]=0 then BFSVisit(v); end Thời gian thực giải thuật BFS tương tự DFS, Θ(|V| + |E|) đồthị biểu diễn danh sách kề danh sách liên thuộc, Θ(|V|2) đồthị biểu diễn ma trận kề, Θ(|V||E|) đồthị biểu diễn danh sách cạnh Bài tập: Bài 1: Mê cung hình chữ nhật kích thước m×n gồm ô vuông đơn vị (m, n ≤ 1000) Trên ô ghi ba kí tự: • O: Nếu ô an toàn • X: Nếu ô có cạm bẫy • E: Nếu ô có nhà thám hiểm đứng Duy có ô ghi chữ E Nhà thám hiểm từ ô sang số ô chung cạnh với ô đứng Một cách thoát khỏi mê cung hành trình qua ô an toàn ô biên Hãy giúp cho nhà thám hiểm hành trình thoát khỏi mê cung qua ô Dữ liệu vào từ tệp văn MECUNG.INP • Dòng 1: Ghi m, n (1