1. Trang chủ
  2. » Công Nghệ Thông Tin

Thuật toán Heuristic

10 2,3K 40
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 92 KB

Nội dung

Thuật toán Heuristic

Tìm hiểu thuật toán HeuristicNguyễn Văn SơnĐối với nhiều bài toán, hoặc không có lời giải, hoặc độ phức tạp tính toán là hàm mũ, hoặc là bài toán NP-đầy đủ…, có nghĩa là nó không có lời giải khả thi, thì thông thường thay vì tìm lời giải tối ưu cho chúng, chúng ta cố gắng tìm lời giải có thể chấp nhận được, đáp ứng được yêu cầu của thực tế. Các lời giải này chính là các thuật toán heuristic.Các thuật toán tìm kiếm luôn luôn đóng vai trò quan trọng trong việc giải các bài toán tin học. Các thuật toán loại này rất phong phú, có thể kể đến như: vét cạn, đệ quy quay lui, nhánh cận, nhị phân…Tuy nhiên, khi gặp những bài toán có không gian tìm kiếm lớn (đặc biệt trong các trò chơi cờ) thì các thuật toán tìm kiếm thông thường không cho kết quả hoặc kết quả không tối ưu (do những hạn chế về thời gian và bộ nhớ). Một hướng tiếp cận độc đáo có thể đáp ứng được đòi hỏi cho nhiều bài toán loại này là dùng thuật toán Heuristic.Thuật ngữ Heuristic xuất phát từ tiếng Hy Lạp là ″heuriskein″ có nghĩa là ″tìm kiếm″ hoặc ″phát minh″. Chắc chắn chúng ta vẫn còn nhớ câu chuyện về nhà bác học Archimedes. Khi phát hiện ra định luật về trọng lượng riêng, ông đã trần truồng chạy ra đường và kêu lớn ″tôi tìm ra rồi″. Thực ra, lúc đó ông đã kêu lên ″heureka″, về sau này người ta đổi từ này thành ″eureka″. Thuật ngữ Heuristic được Feigenbaum Feldman định nghĩa như sau: ″Heuristic là các quy tắc, phương pháp, chiến lược, mẹo giải hay phương cách nào đó nhằm làm giảm khối lượng tìm kiếm lời giải trong không gian bài toán cực lớn″.Tư tưởng chính để giảm khối lượng tìm kiếm là thay vì ″loại bỏ các hướng tìm kiếm chắc chắn không dẫn đến lời giải″, ta hãy ″chọn đi theo hướng có nhiều khả năng dẫn đến lời giải″.Do thuật toán Heuristic được con người sử dụng thường mang đặc trưng của những gợi ý hay lời khuyên, nên các phương pháp dựa trên Heuristic đôi khi không chỉ ra con đường trực tiếp để đạt tới mục đích.Nhiều kết quả nghiên cứu trong trí tuệ nhân tạo cho thấy rằng, tuy có nhiều điểm mạnh nổi bật, nhưng trong một vài lĩnh vực nghiên cứu nào đó thì các phương pháp Heuristic còn bộc lộ những điểm yếu nhất định. Điều phức tạp chính là vì mọi chương trình máy tính phải đảm bảo chắc chắn kết thúc công việc (theo định nghĩa một thuật toán phải đảm bảo tính đúng và tính dừng). Vì vậy, nếu nói rằng một chương trình nào đó sử dụng Heuristic thì kết luận về tính dừng chỉ đúng trong đa số các trường hợp. Do đó, trong phần lớn trường hợp giải quyết bài toán, các chương trình Heuristic có lúc cho kết quả mong đợi, đôi khi lại không.Các Heuristic không chỉ tác động đến các chiến lược tìm kiếm, mà còn ảnh hưởng quyết định tới các chiến lược điều khiển (hướng tìm kiếm trong không gian bài toán và xử lý cạnh tranh). Đối với những bài toán trí tuệ phức tạp, số khả năng có thể lớn tới mức không thể có một máy tính nào dầu hiện đại đến mấy đáp ứng nổi. Do vậy, thủ tục duyệt toàn thể không thể chấp nhận được. Trong phần lớn các bài toán chứng minh định lý sử dụng logic, số khả năng cần phải xét trở lên vô hạn. Việc lựa chọn một nước đi tốt nhất trong trò chơi đòi hỏi phải tìm kiếm trong khoảng 1040 khả năng khác nhau, thậm chí đối với chơi cờ, số khả năng cỡ 10120. Một cách xử lý tốt trong những trường hợp này là sử dụng thao tác rút gọn các hướng tìm kiếm.Vấn đề quan trọng là ở chỗ, chúng ta biết khai thác khéo léo thông tin tại mỗi trạng thái để tìm ra thứ tự ưu tiên và đẩy nhanh quá trình tìm kiếm. Thông thường ta gắn với mỗi trạng thái của bài toán với một số đo (một hàm đánh giá) nào đó để đánh giá mức độ gần đích của nó.Một kỹ thuật Heuristic được coi là hợp lý khi nó cho phép tiến hành đánh giá các khả năng để làm rõ khả năng nào tốt hơn các khả năng còn lại. Những ví dụ điển hình về các hàm đánh giá là các ước lượng khoảng cách đường chim bay từ một đỉnh nào tới đỉnh đỉnh đích trong bài toán xác định đường đi ngắn nhất, hay các đánh giá ước lượng mức độ quan trọng của các quân cờ trong mỗi thế cờ dựa trên tổ hợp các trọng số của chúng…Để minh hoạ cho thuật toán Heuristic, chúng ta cùng nghiên cứu bài toán sau đây: bài toán 8-puzzle (đây là một trò chơi được một nhà thiết kế trò chơi nổi tiếng của Mỹ là Sam Loyd phát minh vào cuối những năm 1870; nó đã trở thành một trò chơi được cực kỳ được ưa chuộng ở Mỹ vào thời điểm đó). Bài toán:Có 8 số mang các giá trị từ 1 tới 8 được sắp xếp vào một bảng các ô vuông kích thước 3x3. Mỗi số đó được xếp vào một ô, có một ô của bảng bỏ trống. Cho trước hai bảng các con số (thể hiện cho trạng thái nguồn và trạng thái đích của bài toán), hãy chỉ ra một dãy các phép chuyển các con số (nếu có) để thu được một một bảng (trạng thái đích) từ bảng còn lại (trạng thái nguồn). Bạn chỉ được phép chuyển các con số lên trên, xuống dưới, sang trái và sang phải từ một ô có con số sang ô trống (bài toán này còn có dạng phức tạp hơn là 15-puzzle).Rõ ràng, đối với bài toán này nếu dùng phương pháp duyệt toàn bộ thì không hợp lý. Để giảm không gian tìm kiếm, ta xây dựng một thứ tự ưu tiên để duyệt các hướng đi. Do đó, khi duyệt thứ tự ưu tiên theo thứ tự giảm dần của khả năng dẫn đến lời giải, ta sẽ có cơ hội tiếp cận đến lời giải nhanh hơn là duyệt một cách mù quáng!.Tuy nhiên, điểm mấu chốt là: làm thế nào để đánh giá khả năng dẫn đến lời giải của một hướng đi? Nếu đánh giá này chính xác, chúng ta sẽ tìm thấy lời giải nhanh hơn còn nếu không thì trong trường hợp xấu nhất, lại trở về vét cạn toàn bộ.Trong bài toán này, ta sử dụng hàm đánh giá ký hiệu là h với ý nghĩa: h(u) cho biết số các chữ số trong trạng thái u không trùng với vị trí của nó trong trạng thái đích. Khi đó, trạng thái có tiềm năng dẫn tới đích nhanh nhất là trạng thái có hàm đánh giá h đạt giá trị min.Thuật toán cho trò chơi 8-puzzle:Một số ký hiệu- Tập P các trạng thái chờ quyết định được tổ chức dưới dạng stack.- Tập Q các trạng thái đã phát triển được tổ chức dưới dạng hàng đợi.- Tập P′ lưu trữ tạm thời các trạng thái kề v của u khi ta phát triển một đỉnh u (v thu được từ u thông qua một phép di chuyển con số).- Biến found. - Hàm father.Thuật toán: Input: trạng thái ban đầu u0 và trạng thái đích ut1.P← { u0 } ; Q ← Φ ; found ← false; P′ ← Φ ;2.While(P ≠ Φ ) and (not found) do2.1. Loại trạng thái u ở đỉnh stack P và đặt nó vào Q:Pop(P,u);Ađ(u,Q);2.2. If u=ut then found ← trueElse for v thuộc kề(u) doIf v không thuộc P hợp Q thenBeginfather (v) ← u;Ađ (v,P′);End;If P′ ≠ Φ thenBeginSắp xếp P′ theo thứ tự tăng của hàm h. Chuyển P′ vào đỉnh stack P sao cho trạng thái nhiều hứa hẹn nhất (có giá trị hàm h nhỏ nhất) ở đỉnh của P.End; (Chú ý: Sau khi chuyển P′ vào đỉnh stack P thì P′ trở thành rỗng.)Output: Nếu found = false thì bài toán vô nghiệm.Nếu found = true thì nghiệm là đường đi từ u0 tới ut được xác định bằng cách sử dụng hàm father.Cây tìm kiếm được hình thành do sử dụng thuật toán Heuristic ở trên được minh hoạ như trong hình vẽ dưới (nét đậm thể hướng tìm kiếm), số ghi cạnh các đỉnh là giá trị của hàm h tại đỉnh đó. Minh hoạ cây tìm kiếm cho trò chơi 8-puzzle bằng thuật toán HeuristicChương trình minh hoạ cho thuật toán Heuristic giải quyết bài toán ở dạng tổng quát được viết bằng ngôn ngữ Pascal như dưới đây. Dữ liệu vào cho trong file SO.INP: dòng đầu là một số n (1<N2-1)-puzzle). Tiếp theo là hai nhóm dòng, mỗi nhóm gồm n dòng (gồm các số được ghi cách nhau một dấu cách) lần lượt minh hoạ cho bảng số nguồn và bảng số đích. Dữ liệu ra được ghi vào file SO.OUT gồm nhiều nhóm dòng, mỗi nhóm gồm n+1 dòng: bắt đầu là một số chỉ thứ tự của bảng số được phát triển tính từ bảng số nguồn và n dòng tiếp theo minh hoạ cho bảng số đó. Nếu không tồn tại lời giải thì ghi một số 0.Ví dụ:SO.INP32 6 31 6 47 0 51 2 38 0 47 6 5SO.OUT12 8 31 47 6 522 31 8 47 6 5 32 31 8 47 6 541 2 38 47 6 551 2 38 46 5Sau đây là toàn văn chương trình:PROGRAM heuristic;{$B-}{$M 65000,0,655360}Uses Crt;Const Max=6;fi=′SO.INP′;fo=′SO.OUT′;Type Vec=Array[1 Max,1 Max] of byte;Item=record Ma:vec;Father,child:longint; End;Pointer =^node; Node=record Infor:item;Next:pointer; End;Node1=array[1 4] of vec;Tp=0 10;VarU :item; Id :longint;Front,rear,top:pointer; P :node1;Dau,dich :vec; Found :boolean;N :2 10; So_pts :tp;I,j :tp;ff:text;PROCEDURE Vi_tri(a:vec;var k,t:TP);Var i,j:1 max;Begin For i:=1 to n do For J:=1 to n doIf a[i,j]=0 thenBegin K:=i; T:=j; Exit; End;End;{minh hoa cho cac phep di chuyen so}PROCEDURE Left(a:vec;var lef:vec;i,j:tp);Begin A[i,j]:=A[i,j+1];A[i,j+1]:=0; Lef:=A;End;PROCEDURE Right(a:vec;var righ:vec;i,j:tp);Begin A[i,j]:=A[i,j-1]; A[i,j-1]:=0; Righ:=A;End;PROCEDURE Up(a:vec;var u:vec;i,j:tp);Begin A[i,j]:=A[i+1,j]; A[i+1,j]:=0; U:=A; End;PROCEDURE Down(a:vec;var dow:vec;i,j:tp);Begin A[i,j]:=A[i-1,j];A[i-1,j]:=0;Dow:=AEnd;PROCEDURE Pop(var Top:pointer;var U:Item);Var Q:Pointer;Begin Q:=Top;Top:=Top^.next;U:=Q^.infor; Dispose(q)End;PROCEDURE Ađ(u:Item;var rear,front:pointer);Var Q:pointer;Begin New(q); Q^.infor:=u;Q^.next:=nil;If front =nil then front:=qElse rear^.next:=q;Rear:=qEnd;FUNCTION Count(a:vec):byte;Var i,j :0 10; Dem :byte;Begin Dem:=0; For i:=1 to n do For j:=1 to n doIf a[i,j]<>Dich[i,j] then dem:= dem+1;Count:=DemEnd;FUNCTION Dung(a,b:vec):boolean;Var i,j:tp;Begin Dung:=false;For i:=1 to n do For J:=1 to n doIf a[i,j]<>b[i,j] then exit;Dung:=true;End;FUNCTION KtrăFront ,top:pointer;a:vec):boolean;Var q :Pointer; Ok :boolean;Begin Ok:=true; Q:=top;While (q<>nil) and ok doif Dung(Q^.infor.ma,A) then ok:=FalseElse Q:=q^.next; Q:=Front;While (q<>nil) and ok doif Dung(Q^.infor.ma,a) then ok:=FalseElse Q:=q^.next; Ktra:=okEnd;PROCEDURE Nhap;Var i,j:1 max;Begin assign(ff,fi);reset(ff);readln(ff,n);For i:=1 to n doFor j:=1 to n doRead(ff,dau[i,j]);For i:=1 to n doFor j:=1 to n do Read(ff,dich[i,j]);close(ff)End;PROCEDURE In_vec(a:vec);Var i,j:byte;Begin For i:= 1 to n doBegin For j:=1 to n doIf a[i,j]<>0 then write(ff,a[i,j]:3) else write(ff,' ');writeln(ff);End;End;FUNCTION Nhap_cx(a:vec):Boolean;Var i,j :byte; S1,s2 :Set of byte;Begin S1:=[];s2:=[];For I:=0 to N*N-1 do s1:=s1+[i];Nhap_cx:=False; For i:=1 to n doFor J:=1 to n doIf not(a[i,j] in s1)or (a[i,j] in s2)then exitElse S2:=s2+[a[i,j]];Nhap_cx:=true;End;PROCEDURE Init;Var Uo:pointer;Begin Clrscr;Nhap;If not Nhap_cx(dau)or not Nhap_cx(dich) thenbegin Writeln('LOI KHI DOC DU LIEU');readln;halt;end;Found:=false;New(Uo);Uô.infor.ma:=Dau;Uô.infor.father:=0;Uô.infor.child:=1;Uô.next:=nil;Top:=Uo;front:=nil;Rear:=nil;End;PROCEDURE Ptu_ke(var p:node1;U:vec;i,j:tp;var so_pts:tp);Var v :vec;Begin If I>1 then Begin Down(u,v,i,j);If ktrăfront,top,v) thenBegin So_pts:=so_pts+1; P[so_pts]:=v;EndEnd;If j>1 thenBegin Right(u,v,i,j);If ktrăfront,top,v) thenBegin So_pts:=so_pts+1;P[so_pts]:=v EndEnd; If jIf ktrăfront,top,v) thenBegin So_pts:=so_pts+1; P[so_pts]:=v; EndEnd;If IIf ktrăfront,top,v) thenBegin So_pts:=so_pts+1;P[so_pts]:=v;EndEnd;End;PROCEDURE Sxep(Var P:node1;so_pts:tp);Var Tg :vec; T,i,j,min :tp; B :array[1 4] of byte;Begin For i:=1 to so_pts do B[i]:=count(p[i]);For i:=1 to so_pts-1 doBegin Min:=i;For j:=i+1 to so_pts doIf b[j] If min>i thenBegin T:=b[i]; B[i]:=b[min];B[min]:=t;Tg:=p[i];P[i]:=p[min];P[min]:=tg; EndEndEnd;PROCEDURE Push(var top:pointer;p:node1;child:longint;so_pts:tp);Var i:tp;v:pointer;Begin For i:=so_pts downto 1 do BeginNew(v); V^.infor.ma:=p[i];V^.infor.father:=child; Id:=id+1;V^.infor.child:=id;V^.next:=top; Top:=v;EndEnd;PROCEDURE In_Kq;Var p :pointer;i,buoc :longint;Begin Buoc:=0;P:=front;I:=1;assign(ff,fo);rewrite(ff);if not found then beginwrite(ff,0);close(ff);exit;end;P:=p^.next;While P<>nil doBegin If p^.infor.father=i thenBeginI:=p^.infor.child; Buoc:=buoc+1;Writeln(ff,buoc);In_vec(P^.infor.ma); End; P:=p^.nextEnd;close(ff);End;BeginClrscr;Init;While (top<>nil) and not(Found) doBegin Pop(Top,U); Ađ(u,Rear,Front);If dung(u.ma,dich) then found:=trueElse Begin Vi_tri(U.ma,i,j); So_pts:=0;Ptu_ke(p,u.ma,i,j,so_pts);sxep(p,so_pts);Push(top,p,u.child,so_pts) EndEnd;In_kq;End.Chú ý: Việc lựa chọn hàm đánh giá cho bài toán trên có thể tính thông qua tổng khoảng cách ngắn nhất (tính theo ô) của từng con số trong trạng thái hiện tại so với vị trí đúng của nó trong trạng thái đích.Một ví dụ khác là bài toán tô màu cho đồ thị. Giả sử G = là một đồ thị không định hướng. Yêu cầu tô màu cho tất cả các đỉnh của G sao cho hai đỉnh được nối bằng một cung thì phải có hai màu khác nhau. Có thể thấy rằng bài toán tô màu này sao cho số màu được dùng là ít nhất là một bài toán NP-đầy đủ. Lúc này, ta tìm một lời giải tốt có thể chấp nhận được theo một thuật toán heuristic như sau:Ban đầu chọn một màu và một đỉnh xuất phát. Ta tô màu đỉnh này và tất cả các đỉnh khác có thể tô được mà vẫn thoả mãn điều kiện của bài toán. Chúng ta chọn màu mới và một đỉnh xuất phát mới (chưa được tô), ta tô đỉnh này và tất cả các đỉnh khác (còn chưa được tô) có thể tô được bằng màu thứ hai, và cứ như vậy…cho đến khi tô hết các đỉnh của G thì thôi.Bài tập 1: Các ô vuông thần bí (đề thi Olympic tin học quốc tế 1996)Kế tục thành công của trò chơi với khối lập phương thần bí, Ngài Rubik sáng tạo ra dạng phẳng của trò chơi này gọi là trò chơi các ô vuông thần bí. Đây là một bảng gồm 8 ô vuông bằng nhau (xem Hình 1).Chúng ta xét bảng trong đó mỗi ô vuông có một màu khác nhau. Các màu được ký hiệu bởi tám số nguyên dương đầu tiên (xem Hình 1). Trạng thái của bảng được cho bởi dãy ký hiệu màu của các ô được viết lần lượt theo chiều kim đồng hồ bắt đầu bởi ô ở góc trái trên và kết thúc tại ô ở góc trái dưới. Ví dụ, trạng thái của bảng trong hình 1 được cho bởi dãy (1, 2, 3, 4, 5, 6, 7, 8). Trạng thái này được gọi là trạng thái khởi đầu (hay trạng thái đích). Có thể dùng 3 phép biến đổi cơ bản đối với bảng có tên là′A′, ′B′, ′C′:′A′: đổi chỗ dòng trên và dòng dưới. Ví dụ sau phép biến đổi ′A′thì hình 1 thành: ′B′: thực hiện một phép hoán vị vòng quanh sang phải. Ví dụ sau phép biến đổi ′B′ thì hình 1 thành:′C′: quay theo chiều kim đồng hồ bốn ô giữa. Ví dụ sau phép biến đổi ′C′ thì hình 1 thành:Biết rằng từ một trạng thái khởi đầu luôn có thể chuyển về một trạng thái bất kỳ bằng cách dùng các phép biến đổi cơ bản nói trên.Hãy viết chương trình tìm các phép biến đổi cơ bản để chuyển bảng từ trạng thái khởi đầu cho trong hình 1 về một trong các trạng thái cho trước (Câu A), bạn sẽ được thêm hai điểm nếu số lượng phép biến đổi tìm được không vượt quá 300 (Câu B).Dữ liệu vào: file INPUT.TXT chứa 8 số nguyên dương trong dòng đầu tiên mô tả trạng thái đích.Dữ liệu ra: trong dòng đầu tiên của file OUTPUT.TXT chứa một số L là số lượng phép biến đổi của dãy các phép biến đổi tìm được. Trong L dòng tiếp theo phải ghi dãy tên các phép biến đổi cơ bản theo trình tự thực hiện, mỗi tên ghi ở vị trí đầu tiên của mỗi dòng.Ví dụ về dữ liệu vào và dữ liệu ra:Bài tập 2: (Bài toán người bán hàng)Người bán hàng có hành trình sao cho mỗi thành phố đi đến đúng một lần và quay trở lại thành phố xuất phát. Hãy tìm một hành trình đi ngắn nhất cho người bán hàng đó.Thuật toán chúng ta vừa nghiên cứu ở trên đã chứng tỏ sự hiệu quả của nó, bởi lẽ thực tiễn ngày nay đã chỉ ra rằng đi đôi với sự phát triển của khoa học và công nghệ thì chúng ta ngày càng gặp nhiều bài toán mà đối với chúng rất khó xác định có tồn tại hay không một lời giải chính xác. Sử dụng thuật toán này cùng với một vài kỹ năng lập trình, bạn đọc có thể dễ dàng viết một vài chương trình trò chơi đơn giản. [...]... màu được dùng là ít nhất là một bài tốn NP-đầy đủ. Lúc này, ta tìm một lời giải tốt có thể chấp nhận được theo một thuật tốn heuristic như sau: Ban đầu chọn một màu và một đỉnh xuất phát. Ta tô màu đỉnh này và tất cả các đỉnh khác có thể tơ được mà vẫn thoả mãn điều kiện của bài toán. Chúng ta chọn màu mới và một đỉnh xuất phát mới (chưa được tô), ta tơ đỉnh này và tất cả các đỉnh khác (cịn chưa . chính là các thuật toán heuristic. Các thuật toán tìm kiếm luôn luôn đóng vai trò quan trọng trong việc giải các bài toán tin học. Các thuật toán loại này. tìm kiếm cho trò chơi 8-puzzle bằng thuật toán HeuristicChương trình minh hoạ cho thuật toán Heuristic giải quyết bài toán ở dạng tổng quát được viết bằng

Ngày đăng: 11/09/2012, 15:00

TỪ KHÓA LIÊN QUAN

w