Nguồn Internet
THUẬ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 x 1 , x 2 , …, x n . Giả sử đã xác định được i-1 thành phần x 1 , x 2 , …, x i-1 ta xác định thành phần x i 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 n i ). 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 x i 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 x i+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 x i-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 x i ) do If <chấp nhận j> then Begin <Xác định x i 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; Var 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 đó a 1 , a 2 , …, a n , 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; END; { 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 8 Thực hiện chương trình ta nhận được: You might also like: . THUẬ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. 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