Thuật toán tìm kiếm leo đồi
N.V.T
Trong lập trình giải toán, các thuật toán tìm kiếmđóng một vai trò cực kỳ quan trọng và rất
quen thuộc đối với chúng ta. Trongbài viết này, xin trình bày với bạn đọc một trong số các
thuật toán tìm kiếmphổ biến: "Thuật toán leo đồi (Hill Climbing Search).
Trước hết, ta nghiên cứu bài toán sau: Trò chơi n
2
-1số (n ∈ N, n > 1).
Bài toán: Có n
2
-1 số mangcác giá trị từ 1 tới n
2
-1 được sắp xếp vào một lưới các ô vuông
kíchthước n x n. Mỗi số đó được gọi là một quân cờ và lướiô đó được gọi là bàn cờ. Có
một vị trí của bàn cờ bỏ trống. Mỗi lần di chuyểnquân, người chơi được phép chuyển một
quân ở vị trí ô tiếp giáp cạnh với ôtrống vào ô trống.
Yêucầu: Từ mộttrạng thái ban đầu (sự sắp xếp ban đầu của các quân trên bàn cờ), hãy thực
hiệncác nước đi hợp lệ để thu được trạng thái kết thúc (trạng thái đích cần đạtđược).
Vídụ: với trò chơi 8 số ta minh họa trạng thái ban đầu và trạng thái kết thúcqua các hình vẽ
dưới đây:
Đểgiải bài toán này, chúng ta sẽ nghĩ ngay tới việc xây dựng một cây tìm kiếm màgốc của
cây tương ứng với trạng thái xuất phát của bàn cờ. Các đỉnh khác củacây tương ứng với
các trạng thái thu được do việc thực hiện các nước đi hợp lệ(các nước đi được phép thực
hiện là: lên trên, xuống dưới, sang trái và sangphải). Với ví dụ trên, ta có cây tìm kiếm sau:
Tiếpđó, ta chỉ việc áp dụng các thuật toán thông dụng như: thuật toán tìm kiếm theochiều
rộng hoặc thuật toán tìm kiếmtheo chiều sâu để tìm ra lời giải.
Việcsuy nghĩ như trên xem ra có tính khả thi (đơn giản, dễ cài đặt), tuy nhiên, dễnhận thấy
rằng nếu số n lớn hơn, ta sẽ phải phát triển một số quá lớn các trạngthái trước khi phát hiện
ra trạng thái đích. Những hạn chế về mặt thời gian và dung lượng bộ nhớ không cho
phépthực hiện điều đó.
Trongthực tế, có nhiều bài toán mà số các trạng thái của nó là rất lớn (như cờ vua,cờ
tướng...), thì việc giải bài toán chỉ có thể thực hiện nếu bằng một cách nàođó ta lược bỏ
những trạng thái thừa, không cần thiết nhằm giảm số lượng trạngthái cần phát triển. Để
làm được điều đó, phải sử dụng khéo léo các thông tin phản hồi nảy sinh trong quá
trìnhtìm kiếm (các thông tin này còn gọi là thông tin cảm tính: HeuristicInformation). Cách
làm này được đưa ra nhằm mục đích lựa chọn được hướng tìmkiếm tốt nhất tại mỗi bước
theo nghĩa: hướng đi đó nhanh dẫn tới trạng tháiđích nhất và nhằm giảm công sức tìm
kiếm.
Thuậttoán tìm kiếm leo đồi đã đáp ứng được yêu cầu trên. Nội dung thuật toán được môtả
như sau:
Bước 1: Nếu trạng thái đầu trùngvới trạng thái đích thì dừng ngay, ngược lại thì chuyển
sang bước 2.
Bước 2: Sử dụng các quy tắc biến đổi để tạo ra 1 tập hợp các trạng tháitừ trạng thái hiện
thời (trong bài toán trên ta có 4 quy tắc biến đổi tương ứngvới 4 phép di chuyển quân).
Bước 3: Với mỗi trạng thái trongtập hợp vừa tạo ra kiểm tra xem đó có phải là trạng thái
đích hay không? Nếuphải thì ngừng việc tìm kiếm, nếu không phải thì ta kiểm tra xem
trạng thái mớinày có tốt hơn (gần trạng thái đích hơn) so với trạng thái đã có hay không?
Nếuquả thật như vậy thì ghi nhận trạng thái này, ngược lại thì bỏ qua.
Bước 4: Trong các trạng thái đượctạo ra (sau khi thực hiện các thao tác ở bước 3), ta ưu
tiên phát triển trạngthái tốt nhất (trạng thái tốt nhất là trạng thái có tiềm năng dẫn tới
đíchnhanh nhất).
Bướcnày nhằm mục đích chuyển hướng tìm kiếm lời giải nhanh đến đích nhất.
Bước 5: Lặp lại từ bước 2.
Đếnđây bạn đọc có thể nhận thấy thuật toán tìm kiếm leo đồi thực chất là thuậttoán tìm
kiếm theo chiều sâu, song tại mỗi bước ta sẽ ưu tiên chọn một trạngthái có hứa hẹn nhanh
tới đích nhất để phát triển trước. Vấn đề quan trọng là ởchỗ biết khai thác khéo léo thông
tinphản hồi để xác định hướng đi tiếp và đẩy nhanh quá trình tìm kiếm.Thông thường ta
gắn mỗi trạng thái của bài toán với một số đo (1 hàm đánh giá)nào đó nhằm đánh giá mức
độ gần đíchcủa nó.
Nhưvậy: Nếu trạng thái hiện thời là u, theo bước 4 của thuật toán trên thì trạngthái v sẽ
được phát triển tiếp theo nếu vẻ kề(u) và hàm đánh giá của vđạt gía trị max (hoặc min).
Phầntiếp theo sẽ trình bày cụ thể thuật toán để giải bài toán trên. Trong bài toánnày, ta sẽ
sử dụng hàm đánh giá ký hiệu là h với ý nghĩa: h(u) cho biết số cácchữ số trong trạng thái
u không trùng với vị trí của nó trong trạng thái đích.Trạng thái có tiềm năng dẫn tới đích
nhanh nhất (được ưu tiên phát triển trước)là trạng thái có hàm đánh giá h đạt giá trị min.
Thuậttoán cho trò chơi n
2
-1 số được mô tả như sau :
Input: Trạng thái ban đầu u
0
và trạng thái đích u
t
1. P:={u
0
} ;{P để lưu các trạng thái chờphát triển được tổ chức dưới dạng Stack }
Q:=Φ ;{để lưu các trạng thái đãphát triển được tổ chức dưới dạng hàng đợi Queue}
P:= Φ ;{P để lưu tạm thời các trạngthái kề với trạng thái đang xét}
found:=false;
2. While (P # y) and (not found) do
2.1.Loại bỏ trạng thái u ở đỉnh stack P và đặt nó vào hàng đợi Q:
Pop(P,u);
Ađ(u,Q);
2.2.if u=u
t
then found:= true
else
For v ẻ kề (u) do
if(v ẽ P U Q) and (h(v)<= max {h(w)| w ờ P U Q } then
Begin
father (v):=u;
Ađ (v,P?);
End;
if P <> f then
Begin
Sắp xếp các trạng thái trong P theotrật tự tăng của hàm h;
Chuyển các trạng thái trong P vàođỉnh của stack P sao cho
trạng thái có giá trị hàm h nhỏ nhất ở đỉnh của P;
End;
Output: Nếu found = false thì bàitoán không có lời giải.
Nếu found = true thì lời giải là đường đi từu
0
tới u
t
được xác định bằng cách sử
dụng hàm father.
Chú ý:Saukhi chuyển các trạng thái từ P vào P thì P= f
h(v
1
) ≤ h(v
2
) ≤.... ≤ h(v
k
)
Vớiví dụ trên, cây tìm kiếm được hình thành bởi tìm kiếm leo đồi có các trạng tháiđược
phát triển như hình vẽ dưới (nét đậm thể hiện hướng tìm kiếm), các số ghicạnh mỗi đỉnh là
giá trị của hàm h tại đỉnh đó.
Thuậttoán này có tên gọi là thuật toán tìm kiếm leo đồi, vì tư tưởng của nó tương tựnhư
trường hợp: Một người ở vị trí chân đồi u
0
và muốn leo lên đỉnhđồi tại vị trí u
t
. Anh ta
chọn một đỉnh cao nhất trong số các đỉnhmà anh ta có thể đến được (từ vị trí đang đứng)