Thuật toán quay lui (Back track)

Một phần của tài liệu Bài giảng Các kĩ thuật lập trình: Phần 1 (Trang 66 - 68)

Phƣơng pháp sinh kế tiếp có thể giải quyết đƣợc các bài toán liệt kê khi ta nhận biết đƣợc cấu hình đầu tiên của bài toán. Tuy nhiên, không phải cấu hình sinh kế tiếp nào cũng đƣợc sinh một cách đơn giản từ cấu hình hiện tại, ngay kể cả việc phát hiện cấu hình ban đầu cũng không phải dễ tìm vì nhiều khi chúng ta phải chứng minh sự tồn tại của cấu hình. Do vậy, thuật toán sinh kế tiếp chỉ giải quyết đƣợc những bài toán liệt kê đơn giản.

Để giải quyết những bài toán tổ hợp phức tạp, ngƣời ta thƣờng dùng thuật toán quay lui (Back Track) sẽ đƣợc trình bày dƣới đây.

Nội dung chính của thuật toán này là xây dựng dần các thành phần của cấu hình

bằng cách thử tất cả các khả năng. Giả sử cần phải tìm một cấu hình của bài toán x = (x1,

x2, . ., xn) mà i-1 thành phần x1, x2, . ., xi-1 đã đƣợc xác định, bây giờ ta xác định thành phần thứ i của cấu hình bằng cách duyệt tất cả các khả năng có thể có và đánh số các khả

năng từ 1 . .ni. Với mỗi khả năng j, kiểm tra xem j có chấp nhận đƣợc hay không. Khi đó

có thể xảy ra hai trƣờng hợp:

Nếu chấp nhận j thì xác định xi theo j, nếu i=n thì ta đƣợc một cấu hình cần tìm,

ngƣợc lại xác định tiếp thành phần xi+1.

Nếu thử tất cả các khả năng mà không có khả năng nào đƣợc chấp nhận thì quay lại bƣớc trƣớc đó để xác định lại xi-1.

Điểm quan trọng nhất của thuật toán là phải ghi nhớ lại mỗi bƣớc đã đi qua, những khả năng nào đã đƣợc thử để tránh sự trùng lặp. Để nhớ lại những bƣớc duyệt trƣớc đó, chƣơng trình cần phải đƣợc tổ chức theo cơ chế ngăn xếp (Last in first out). Vì vậy, thuật toán quay lui rất phù hợp với những phép gọi đệ qui. Thuật toán quay lui xác định thành phần thứ i có thể đƣợc mô tả bằng thủ tục Try(i) nhƣ sau:

void Try( int i ) { int j; for ( j = 1; j < ni; j ++) { if ( <Chấp nhận j >) { <Xác định xi theo j> if (i==n) <Ghi nhận cấu hình>; else Try(i+1); } } }

Có thể mô tả quá trình tìm kiếm lời giải theo thuật toán quay lui bằng cây tìm kiếm lời giải sau:

Gốc

Khả năng chọn x2 với x1 đã chọn

Khả năng chọn x3 với x1, x2 đã chọn

Hình 3.1. Cây liệt kê lời giải theo thuật toán quay lui.

Một phần của tài liệu Bài giảng Các kĩ thuật lập trình: Phần 1 (Trang 66 - 68)