Nguồn Internet
Trang 1THUẬT TOÁN QUAY LUI VÀ MỘT VÀI VÍ DỤ
Thuật toán quay lui dùng để giải lớp bài toán liệt kê hay bài toán tối ưu Với thuật toán này cho phép chúng ta giải quyết một số bài toán kinh điển một cách dễ dàng như: Bài toán người giao hàng, bài toán con mã đi tuần, bài toán 8 hậu, bài toán tìm đường trong mê cung… Thuật toán này có thể mô tả như sau:
Giả thiết cấu hình cần tìm được mô tả bằng một bộ gồm n thành phần x1, x2, …, xn Giả sử đã xác định được i-1 thành phần x1, x2, …, xi-1 ta xác định thành phần xi bằng cách duyệt tất cả các khả năng có thể đề cử cho nó (đánh số các khả năng từ 1 đến ni) Với mỗi khả năng j, kiểm tra xem j có chấp nhận được hay không Xẩy ra hai trường hợp:
Nếu chấp nhận j thì xác định xi theo j, sau đó nếu i=n thì ta được một cấu hình, còn trái lại ta tiến hành việc xác định 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
Thuật toán quay lui có thể được mô tả bằng đoạn mã giả lệnh sau:
{Thủ tục này thử cho x i nhận lần lượt các giá trị mà nó có thể nhận}
Procedure Try(i);
For (mọi khả năngj có thể gán cho xi) do
If <chấp nhận j> then
Begin
<Xác định xi theo j>
If i=n then <ghi nhận một cấu hình>
Else Try(i+1);
End
(Thuật toán quay lui sẽ bắt đầu bằng lời gọi Try(1);)
Ta có thể trình bày quá trình tìm kiếm lời giải quả thuật toán quay lui bằng cây sau:
Ví dụ 1 Liệt kê các xâu nhị phân có độ dài n không chứa hai số 0 liên tiếp.
Chương trình sau viết trong môi trường Borland Pascal
uses wincrt;
Trang 2Var a:array[1 100] of 0 1; n, dem,k:integer; Procedure inxau ;
var i:integer;
begin
dem:=dem+1;
for i:=1 to n do write(a[i]);
writeln;
end;
Procedure try(i:integer);
var j, k: integer;b: boolean;
begin
for j:=0 to 1 do
begin
if (i>1) and (a[i-1]=0) and (j=0) then continue; a[i]:=j;
if (i=n)then
inxau
else try(i+1);
end;
end;
BEGIN
write('Nhap n=');
readln(n); dem:=0;
try(1);
writeln('so xau thoa man:', dem);
readln;
END
Ví dụ 2 Liệt kê tất cả các phần tử của
D =
Trong đó a1, a2, …, an, b là các số nguyên dương Program Liet_ke;
Uses wincrt;
Var
A:Array[1 100] of byte;
X:Array[1 100] of 0 1;
B, Dem:Word;
N:Byte;
{ Doc du lieu tu tep }
Procedure Init;
Var
F:Text;
I:Byte;
BEGIN
Assign(F,'LIETKE.INP');
Reset(F);
Readln(F,N);
For I:=1 to N do
Read(F,A[I]);
Readln(F,B);
Close(F);
Dem:=0;
Trang 3END;
{ In day }
Procedure In_day(K:Byte);
Var
I:Byte;
BEGIN
Dem:=Dem+1;
Write(Dem:4,': ');
For I:=1 to K do
Write(X[I]:2);
For I:=K+1 to N do
Write(0:2);
Writeln;
END;
{ Ham tinh tong}
Function Tong(K:Byte):Word;
Var
I:Byte;
S:Word;
Begin
S:=0;
For I:=1 to K do
S:=S+A[I]*X[I];
Tong:=S;
End;
{ Quay lui }
Procedure Try(I:Byte);
Var
S:Word;
J:0 1;
Begin
S:=Tong(I-1);
For J:=0 to 1 do
Begin
X[I]:=J;
If Tong(I)=B then
In_day(I)
Else
If (TONG(I)<B) And (I<N) Then Try(I+1);
End;
End;
{ Than chuong trinh chinh}
BEGIN
Init;
Try(1);
Readln;
END
Với tệp LIETKE.INP có nội dung:
4
2 4 4 2
Trang 4Thực hiện chương trình ta nhận được:
You might also like: