Bài giảng Phân tích và thiết kế giải thuật - Chương 6: Giải thuật quay lui
Một phương pháp tổng quát để giải quyết vấn đề: thiết kế giải thuật tìm lời giải cho bài tóan không phải là bám theo một tập qui luật tính tóan được xác định mà là bằng cách thử và sửa sai (trial and error).
Khuôn mẫu thông thường là phân rã quá trình thử và sửa sai thành những công tác bộ phận. Thường thì những công tác bộ phận này được diễn tả theo lối đệ quy một cách thuận tiện và bao gồm việc thăm dò một số hữu hạn những công tác con.
Ta có thể coi toàn bộ quá trình này như là một quá trình tìm kiếm (search process) mà dần dần cấu tạo và duyệt qua một cây các công tác con.
Chương 6Giải thuật quay lui Giải thuật quay lui Giải thuật nhánh-và-cận Giải thuật quay lui Một phương pháp tổng quát để giải quyết vấn đề: thiết kế giải thuật tìm lời giải cho bài tóan không phải là bám theo một tập qui luật tính tóan được xác định mà là bằng cách thử và sửa sai (trial and error). Khuôn mẫu thông thường là phân rã quá trình thử và sửa sai thành những công tác bộ phận. Thường thì những công tác bộ phận này được diễn tả theo lối đệ quy một cách thuận tiện và bao gồm việc thăm dò một số hữu hạn những công tác con. Ta có thể coi toàn bộ quá trình này như là một quá trình tìm kiếm (search process) mà dần dần cấu tạo và duyệt qua một cây các công tác con. Cho một bàn cờ n n với n2 ô. Một con hiệp sĩ – được di chuyển tuân theo luật chơi cờ vua – được đặt trên bàn cở tại ô đầu tiên có tọa độ x0, y0. Vấn đề là tìm một lộ trình gồm n2 –1 bước sao cho phủ toàn bộ bàn cờ (mỗi ô được viếng đúng một lần). Cách rõ ràng để thu giảm bài toán phủ n2 ô là xét bài toán, hoặc là - thực hiện bước đi kế tiếp, hay - phát hiện rằng không kiếm được bước đi hợp lệ nào. Bài toán đường đi của con hiệp sĩ (The Knight’s Tour Problem) procedure try next move; begin initialize selection of moves; repeat select next candidate from list of next moves; if acceptable then begin record move; if board not full then begin try next move; (6.3.1) if not successful then erase previous recording end end until (move was successful) (no more candidates) end Chúng ta diễn tả bàn cờ bằng một ma trận h. type index = 1..n ; var h: array[index, index] of integer; h[x, y] = 0: ô chưa hề được viếng h[x, y] = i: ô đã được viếng tại bước chuyển thứ i (1 i n2) Điều kiện “board not full” có thể được diễn tả bằng “i , có 8 khả năng để chọn ô kế tiếp để đi tới. Chúng được đánh số từ 1 đến 8 như sau: Sự tinh chế sau cùng Cách đơn giản nhất để đạt được tọa độ u, v từ x, y là bằng cách cọng độ sai biệt toạ độ tại hai mảng a và b. Và k được dùng để đánh số ứng viên (candidate) kế tiếp. program knightstour (output); const n = 5; nsq = 25; type index = 1..n var i,j: index; q: boolean; s: set of index; a,b: array [1..8] of integer; h: array [index, index] of integer; procedure try (i: integer; x, y: index; var q:boolean); var k,u,v : integer; q1: boolean; begin k:=0; repeat k:=k+1; q1:=false; u:=x+a[k]; v:=y+b[k]; if (u in s) (v in s) then if h[u,v]=0 then begin h[u,v]:=i; if i với n = 5. Từ thí dụ trên ta đi đến với một kiểu “giải quyết vấn đề” mới: Đặc điểm chính là “bước hướng về lời giải đầy đủ và ghi lại thông tin về bước này mà sau đó nó có thể bị tháo gỡ và xóa đi khi phát hiện rằng bước này đã không dẫn đến lời giải đầy đủ, tức là một bước đi dẫn đến “tình thế bế tắc”(dead-end). (Hành vi này được gọi là quay lui -bactracking.) procedure try; begin intialize selection of candidates; repeat select next; if acceptable then begin record it; if solution incomplete then begin try next step; (6.3.3) if not successful then cancel recording end end until successful no more candidates end Khuôn mẫu tổng quát của giải thuật quay lui procedure try (i: integer); var k : integer; begin k:=0; repeat k:=k+1; select k-th candidate; if acceptable then begin record it; if i Z. Hãy giải bài toán bằng một giải thuật quay lui. Cây không gian trạng thái của bài toán này được cho ở hình vẽ sau: X =1 X =2 Y = 1 Y=2 Y = 1 Y=2 Z =1 Z =2 Z=1 Z=2 lời giải Hình 6.9 Thí dụ về cây Không Gian Trạng Thái Độ phức tạp của giải thuật quay lui Thời gian tính toán của các giải thuật quay lui thường là hàm mũ (exponential). Nếu mỗi nút trên cây không gian trạng thái có trung bình nút con, và chiều dài của lối đi lời giải là N, thì số nút trên cây sẽ tỉ lệ với N. Thời gian tính toán của giải thuật đệ quy tương ứng với số nút trên cây không gian trạng thái nên có độ phức tạp hàm mũ. Giải thuật nhánh và cận (branch-and-bound) Bài toán người thương gia du hành (TSP): cho một tập các thành phố và khoảng cách giữa mỗi cặp thành phố, tìm một lộ trình đi qua tất cả mọi thành phố sao cho tổng khoảng cách của lộ trình nhỏ hơn M. Điều này dẫn đến một bài toán khác: cho một đồ thị vô hướng, có cách nào để nối tất cả các nút bằng một chu trình đơn hay không. Đây chính là bài toán Chu trình Hamilton (HCP). Để giải bài toán (HCP), ta có thể cải biên giải thuật tìm kiếm theo chiều sâu trước (DFS) để giải thuật này có thể sinh ra mọi lối đi đơn mà đi qua mọi đỉnh trong đồ thị. Tìm kiếm vét cạn: Giải thuật DFS cải biên sinh ra mọi lối đi đơn Điều này có thể thực hiện được bằng cách sửa lại thủ tục visit như sau: procedure visit( k: integer); var t: integer; begin id := id +1; val[k]:= id; for t:= 1 to V do if a[k, t] then if val[k]= 0 then visit(t); id := id –1; val[k] := 0 end; Thủ tục đệ quy này có thể sinh ra mọi lối đi đơn từ một đỉnh khởi đầu nào đó. Ví dụ: id :=0; for k:= 1 to V do val[k]:=0; visit(1); Một thí dụ về bài toán TSP Tìm kiếm vét cạn các lối đi đơn Từ giải thuật sinh tất cả các lối đi đơn đến giải thuật giải bài toán TSP Ta có thể cải biên thủ tục visit ở trên để có thể nhận diện chu trình Hamilton bằng cách cho nó kiểm tra xem có tồn tại một cạnh nối từ đỉnh k về đỉnh 1 xuất phát khi val[k]=V hay không. Trong thí dụ trên, xem hình vẽ, ta tìm thấy 2 chu trình Hamilton là A F D B C E L M J K I H G A G H I K J M L E C B D F và hai chu trình này chỉ là một. Chương trình nhận diện chu trình Halmiton có thể được sửa đổi để có thể giải bài toán TSP bằng cách theo dõi chiều dài của lối đi hiện hành trong mảng val, và theo dõi lối đi có chiều dài nhỏ nhất trong số các chu trình Hamilton tìm thấy. Ý tưởng nhánh và cận Khi áp dụng giải thuật DFS cải biên để sinh ra mọi lối đi đơn, trong quá trình tìm kiếm một lối đi tốt nhất (tổng trọng số nhỏ nhất) cho bài toán TSP, có một kỹ thuật tỉa nhánh quan trọng là kết thúc sự tìm kiếm ngay khi thấy rằng nó không thể nào thành công được. Giả sử một lối đi đơn có chi phí x đã được tìm thấy. Thì thật vô ích để duyệt tiếp trên lối đi chưa-đầy-đủ nào mà chi phí cho đến hiện giờ đã lớn hơn x. Điều này có thể được thực hiện bằng cách không gọi đệ quy thủ tục visit nếu lối đi chưa-đầy-đủ hiện hành đã lớn hơn chi phí của lối đi đầy đủ tốt nhất cho đến bây giờ. Ý tưởng nhánh và cận (tt.) Rõ ràng ta sẽ không bỏ sót lối đi chi phí nhỏ nhất nào nếu ta bám sát một chiến lược như vậy. Kỹ thuật tính cận (bound) của các lời giải chưa-đầy-đủ để hạn chế số lời giải phải dò tìm được gọi là giải thuật nhánh và cận. Giải thuật này có thể áp dụng khi có chi phí được gắn vào các lối đi.
File đính kèm:
- Bài giảng Phân tích và thiết kế giải thuật - Chương 6 Giải thuật quay lui.ppt