Chương 4 của luận văn trình bày về việc tổng quát hóa một số thuật giải tìm kiếm. Việc tổng quát hóa xuất phát bằng cách xây dựng thuật giải tìm kiếm tổng quát và mở rộng dần sang các thuật giải đặc thù khác như tìm kiếm theo chiều sâu, tìm kiếm theo chiều rộng đến các thuật giải heuristics, thuật giải leo đồi, thuật giải A* Phần còn lại của chương 4 là một số ví dụ việc áp dụng khung thuật giải tìm kiếm này cho từng thuật toán tìm kiếm cụ th ể.
14 trang |
Chia sẻ: vietpd | Lượt xem: 2605 | Lượt tải: 4
Bạn đang xem nội dung tài liệu Thiết lập một số thuật giải tìm kiếm, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
53
Chương 4
Thiết lập một số thuật giải tìm kiếm
Chương 4 của luận văn trình bày về việc tổng quát hóa một số thuật giải tìm kiếm.
Việc tổng quát hóa xuất phát bằng cách xây dựng thuật giải tìm kiếm tổng quát và
mở rộng dần sang các thuật giải đặc thù khác như tìm kiếm theo chiều sâu, tìm
kiếm theo chiều rộng … đến các thuật giải heuristics, thuật giải leo đồi, thuật giải
A* … Phần còn lại của chương 4 là một số ví dụ việc áp dụng khung thuật giải tìm
kiếm này cho từng thuật toán tìm kiếm cụ thể.
4.1 Họ thuật giải tìm kiếm
Bài toán tìm kiếm là một trong những bài toán cơ bản nhưng quan trọng bật nhất
của khoa học máy tính. Yêu cầu đặt ra của bài toán chỉ đơn giản là tìm một lời giải
thỏa mãn bài toán bằng cách duyệt qua một số ứng viên trong không gian tìm kiếm.
Mỗi thứ tự chờ duyệt của các ứng viên trong không gian tìm kiếm này lại trở thành
mỗi thuật giải khác nhau. Ví dụ thứ tự chờ duyệt phần tử của thuật giải tìm kiếm
theo chiều sâu theo cơ chế “vào sau ra trước” rõ ràng khác hẳn với thứ tự chờ duyệt
“vào trước ra trước” của thuật giải tìm kiếm theo chiều rộng.
54
Các bài toán tìm kiếm được phân loại như sau:
- Tìm kiếm không có thông tin: Một thuật giải tìm kiếm không có thông tin
là thuật giải không tính đến bản chất cụ thể của bài toán. Khi đó, các thuật
giải dạng này có thể được cài đặt tổng quát, và cùng một cài đặt có thể được
sử dụng trong một diện rộng các bài toán (do sử dụng trừu tượng hóa).
Nhược điểm của các thuật giải này là phần lớn các không gian tìm kiếm có
kích thước cực kì lớn. Thuật giải tìm kiếm không có thông tin được phân loại
như sau:
o Tìm kiếm trên danh sách: Có lẽ các thuật giải tìm kiếm trên danh
sách là loại thuật giải tìm kiếm cơ bản nhất. Mục đích là tìm trong một
tập hợp một phần tử chứa một khóa có giá trị cho trước. Do đây là
một bài toán thường gặp trong khoa học máy tính, nên độ phức tạp
tính toán của các thuật giải này đã được nghiên cứu kỹ càng. Thuật
giải đơn giản nhất là tìm kiếm tuyến tính. Thuật giải này kiểm tra từng
phần tử trong danh sách theo thứ tự của danh sách đó. Nó có thời gian
chạy khá lớn: ( ), trong đó n là số phần tử trong danh sách, nhưng
có thể sử dụng thẳng cho một danh sách bất kỳ mà không cần tiền xử
lý. Tìm kiếm nhị phân là một thuật giải cao cấp hơn với thời gian
chạy là ( ). Đối với các danh sách lớn, thuật giải này tốt hơn
hẳn tìm kiếm tuyến tính, nhưng nó đòi hỏi danh sách phải được sắp
xếp từ và có khả năng truy xuất ngẫu nhiên. Tìm kiếm nội suy tốt hơn
tìm kiếm nhị phân đối với các danh sách rất lớn với phân bố gần đều.
o Tìm kiếm trên cây: Tìm kiếm trên cây là trung tâm của các kỹ thuật
tìm kiếm. Các thuật giải này tìm kiếm trên các cây gồm các nút, cây
này có thể là cây tường minh hoặc được xây dựng dần trong quá trình
tìm kiếm. Nguyên lý cơ bản là: một nút được lấy ra từ một cấu trúc dữ
liệu, các nút con của nó được xem xét và bổ sung vào cấu trúc dữ liệu
đó. Bằng cách thao tác trên cấu trúc dữ liệu này, cây tìm kiếm được
duyệt theo các thứ tự khác nhau, chẳng hạn theo từng mức (tìm kiếm
55
theo chiều rộng) hoặc đi tới một nút lá trước rồi quay lui (tìm kiếm
theo chiều sâu). Các ví dụ khác về tìm kiếm trên cây bao gồm: tìm
kiếm lặp sâu dần, tìm kiếm chiều sâu giới hạn, tìm kiếm hai chiều và
tìm kiếm chi phí đều.
o Tìm kiếm trên đồ thị: Nhiều bài toán về lý thuyết đồ thị có thể được
giải quyết bằng các thuật giải tìm kiếm, chẳng hạn thuật giải Dijkstra,
thuật giải Kruskal, thuật giải láng giềng gần nhất và thuật giải Prim.
Các thuật giải này có thể được coi là các mở rộng của các thuật giải
tìm kiếm trên cây.
- Tìm kiếm có thông tin: Trong tìm kiếm có thông tin, người ta sử dụng một
đánh giá heuristic đặc thù cho bài toán cần giải quyết với vai trò hướng dẫn
cho quá trình tìm kiếm. Một cách đánh giá heuristic tốt sẽ làm cho quá trình
tìm kiếm có thông tin hoạt động hiệu quả hơn hẳn một phương pháp tìm
kiếm không có thông tin bất kỳ. Có một vài thuật giải tìm kiếm có thông tin
nổi trội dành cho danh sách. Một trong số đó là một bảng băm với một hàm
băm là một heuristic đựa trên bài toán đang được giải. Đa số các thuật giải
tìm kiếm có thông tin đều là tìm kiếm trên cây. Trong đó có tìm kiếm theo
lựa chọn tốt nhất và A*. Cũng như các thuật giải không có thông tin, các
thuật giải này có thể được mở rộng để làm việc trên cả các đồ thị.
- Tìm kiếm đối kháng: Trong các trò chơi như cờ vua hay cờ tướng, có một
cây trò chơi bao gồm tất cả các nước đi có thể của cả hai đấu thủ và các cấu
hình bàn cờ là kết quả của các nước đi đó. Ta có thể tìm kiếm trên cây này để
có được một chiến lược chơi hiệu quả. Dạng bài toán này có đặc điểm độc
nhất vô nhị là ta phải tính đến mọi nước đi mà đối thủ của ta có thể sử dụng.
Để làm điều này, các chương trình máy tính chơi cờ, cũng như các dạng khác
của trí tuệ nhân tạo như lập kế hoạch tự động (machine planning), thường sử
dụng các thuật giải tìm kiếm như thuật giải minimax, tỉa cây tìm kiếm, và tỉa
cây alpha-beta (alpha-beta pruning).
56
- Tìm kiếm thỏa mãn ràng buộc: Đây là một loại tìm kiếm để giải quyết các
bài toán thỏa mãn ràng buộc mà trong đó, thay vì tìm một đường đi, lời giải
chỉ đơn giản là một tập các giá trị được gán cho một tập các biến. Do các
biến có thể được xử lý theo thứ tự tùy ý, các thuật giải thông thường dành
cho tìm kiếm trên cây rất không hiệu quả. Các phương pháp giải các bài toán
ràng buộc bao gồm tìm kiếm tổ hợp và quay lui, cả hai đều tận dụng các đặc
điểm tự do có liên quan đến các bài toán ràng buộc.
- Và một số loại khác: các thuật giải tìm xâu kí tự con, thuật giải tabu, thuật
giải di truyền, thuật giải mô phỏng tôi luyện … cũng thuộc họ giải thuật tìm
kiếm này.
Trong khuôn khổ của luận văn, chúng tôi chỉ đề cập đến một số các thuật giải tìm
kiếm thông dụng như tìm kiếm theo chiều sâu, tìm kiếm theo chiều rộng, thuật giải
A* hay thuật giải leo đồi …
4.2 Xây dựng thuật giải tìm kiếm tổng quát
Để xây dựng thuật giải tìm kiếm tổng quát, ta xét điểm tương đồng về bản chất của
các thuật giải tìm kiếm. Về cơ bản, hầu hết các thuật giải tìm kiếm đều lần lượt tìm
kiếm ứng viên lời giải trong không gian tìm kiếm và kiểm tra đây có phải lời giải
của bài toán hay không? Thuật giải sẽ dừng khi tìm được lời giải hoặc đã duyệt hết
không gian tìm kiếm. Mã giả thuật giải tìm kiếm tổng quát được mô tả trong bảng
4-1.
Bảng 4-1 Mã giải thuật giải tìm kiếm
Thủ tục: tìm kiếm
1. Bắt đầu với x là một lời giải bất kì của không gian tìm kiếm
2. Nếu x là lời giải cần tìm. Dừng thuật giải à Thành công.
3. Nếu x không là lời giải cần tìm. Thực hiện tiếp tục bước 2
với x là phần tử kế tiếp trong danh sách chờ duyệt. Nếu
không còn phần tử nào chưa tìm thì dừng thuật giải à Thất
bại.
57
Từ mã giả trên, ta xây dựng khung giải thuật tìm kiếm kế thừa từ khung giải thuật
tổng quát đã trình bày ở chương 2 như sau. Lớp ℎ kế thừa và cái đặt
thuật giải tìm kiếm tổng quát () kế thừa từ lớp giải quyết bài toán tổng quát . Hàm ℎ() được gọi từ hàm () sẽ thực hiện một số lời
gọi đến các hook của lớp thuật giải tìm kiếm tổng quát ℎ , cụ thể là
hàm tạo danh sách chờ duyệt của các ứng viên () . Hàm () này sẽ trả về một đối tượng biểu diễn danh sách
các ứng viên sẽ được duyệt. Thao tác trên lớp này sẽ được thực thi tại các
lớp duyệt danh sách ứng viên của thuật giải tìm kiếm cụ thể thông qua các hàm
hook: (), (), () …
Bảng 4-2 Thuật giải tìm kiếm tổng quát
class SearchSolver implements Solver {
public SearchSolution solveBySearch(SearchProblem problem) {
// khởi tạo iterator danh sách chờ duyệt ứng viên
SearchStrategy.Iterator iterator =
strategy.createExploringList(problem);
// lặp khi còn phần tử trong danh sách chờ duyệt
while (!iterator.isEmpty()) {
// lấy một ứng viên trong danh sách chờ duyệt
Object candidate = iterator.select();
// nếu ứng viên này là lời giải, chọn ứng viên làm lời giải
// và dừng việc lặp
if (problem.isSolution(candidate) {
return SearchSolution.makeSolution(candidate);
}
// mở rộng danh sách ứng viên chờ duyệt
iterator.explore(problem, candidate);
}
return SearchSolution.makeSolution(null);
}
}
interface SearchProblem extends Problem {
58
boolean isSolution(Object choices);
Object getInitState();
Iterator explore(Object candidate);
};
interface SearchSolution extends Solution {}
abstract class SearchStrategy implements Strategy {
static abstract class Iterator {
public abstract boolean isNotEmpty ();
public abstract Object select ();
public abstract void explore (SearchProblem p, Object c);
public abstract void add(Object c);
}
// tạo danh sách chờ duyệt các ứng viên
protected abtract Iterator createExploringList(SearchProblem p);
}
Với cách triển khai như trên, ta có thể mô hình hóa lại khung giải thuật tìm kiếm
tương tự cách mô hình hóa các thuật giải ở chương 3 như Hình 5-1.
Hình 4-1 Thuật giải tìm kiếm tổng quát
59
4.3 Các thuật giải tìm kiếm cụ thể
Sau khi xây dựng xong giải thuật tìm kiếm tổng quát, ta lần lượt bổ sung vào khung
giải thuật tìm kiếm các giải thuật tìm kiếm cụ thể. Các giải thuật tìm kiếm này sẽ
lần lượt kế thừa thuật giải tìm kiếm tổng quát và kế thừa các hàm hook liên quan
đến thứ tự chờ duyệt của không gian tìm kiếm.
4.3.1 Thuật giải tìm kiếm ưu tiên chiều sâu
Thuật giải tìm kiếm ưu tiên chiều sâu (depth-first-search) là một dạng thuật giải tìm
kiếm thông tin không đầy đủ. Quá trình tìm kiếm bắt đầu từ một phần tử trong
không gian tìm kiếm rồi duyệt tiếp phần tử kế tiếp chưa được duyệt của phần tử này.
Bước lặp trên được thực hiện liên tục đến khi phần tử vừa duyệt là không còn phần
tử nào kế tiếp, thuật giải sẽ quay lui lại phần tử mới vừa duyệt ở bước kế trước. Khi
thực thi thuật giải dưới dạng không đệ quy, thứ tự các phần tử chờ duyệt sẽ được
lần lượt bổ sung vào một ngăn xếp.
Với bản chất thuật giải như vậy, ta nhận thấy thuật giải tìm kiếm ưu tiên chiều sâu
sẽ kế thừa thuật giải tìm kiếm tổng quát với thứ tự của danh sách chờ duyệt là “vào
sau ra trước”. Ta xây dựng lớp thuật giải tìm kiếm ưu tiên chiều sâu ℎ ℎ kế thừa từ ℎ trong đó hàm hook () sẽ tạo ra một đối tượng ℎ kế thừa từ ℎ . . ℎ sẽ hoạt động theo cơ chế “vào
sau ra trước”. Khi cài đặt bằng ngôn ngữ lập trình Java, ta có thể sử dụng một hoặc một với thao tác thêm phần tử vào đầu
danh sách và lấy phần tử ở cuối danh sách.
Mã giã thuật giải tìm kiếm ưu tiên chiều sâu cài đặt kế thừa từ thuật giải tìm kiếm
tổng quát được mô tả trong Bảng 4-3.
60
Bảng 4-3 Thuật giải tìm kiếm ưu tiên chiều sâu
class DepthFirstSearch extends SearchStrategy {
class DepthFirstIterator extends SearchStrategy.Iterator {
// cài đặt lớp duyệt ứng viên theo cơ chế vào sau ra trước
// với phần tử ban đầu bất kì theo yêu cầu của bài toán
}
protected Iterator createExploringList (SearchProblem p) {
return new DepthFirstIterator (p);
}
}
4.3.2 Thuật giải tìm kiếm ưu tiên chiều rộng
Thuật giải tìm kiếm ưu tiên chiều rộng (breadth-first-search) là một dạng thuật giải
tìm kiếm thông tin không đầy đủ. Quá trình tìm kiếm bắt đầu từ một phần tử trong
không gian tìm kiếm rồi duyệt qua tất cả phần tử kế tiếp chưa được duyệt của phần
tử này. Sau đó, ứng với mỗi phần tử kế đó, thuật giải lại duyệt hết các phần tử kế
của nó. Và liên tục lặp như vậy đến khi tìm ra lời giải hoặc thuật giải đã duyệt qua
tất cả phần tử của không gian tìm kiếm. Khi thực thi thuật giải dưới dạng không đệ
quy, thứ tự các phần tử chờ duyệt sẽ được lần lượt bổ sung vào một hàng đợi.
Với bản chất thuật giải như vậy, ta nhận thấy thuật giải tìm kiếm ưu tiên chiều rộng
sẽ kế thừa thuật giải tìm kiếm tổng quát với thứ tự của danh sách chờ duyệt là “vào
trước ra trước”. Tương tự như ℎ ℎ, ta xây dựng lớp thuật giải tìm
kiếm ưu tiên chiều rộng ℎ ℎ kế thừa từ ℎ trong
đó hàm hook () sẽ tạo ra một đối tượng ℎ hoạt động theo cơ chế “vào trước ra trước”. Khi cài đặt
bằng ngôn ngữ lập trình Java, ta có thể sử dụng một hoặc một với thao tác thêm phần tử vào cuối danh sách và lấy
phần tử ở cuối danh sách.
61
Mã giã thuật giải tìm kiếm ưu tiên chiều rộng cài đặt dựa trên khung thuật giải tìm
kiếm được mô tả trong Bảng 4-4.
Bảng 4-4 Thuật giải tìm kiếm ưu tiên chiều rộng
class BreadthFirstSearch extends SearchStrategy {
class BreadthFirstIterator extends SearchStrategy.Iterator {
// cài đặt lớp duyệt ứng viên theo cơ chế vào trước ra trước
// với phần tử đầu tiên bất kì theo yêu cầu của bài toán
}
protected Iterator createExploringList (SearchProblem p) {
return new BreadthFirstIterator (p);
}
}
4.3.3 Thuật giải tìm kiếm ưu tiên lựa chọn tốt nhất
4.3.3.1 Thuật giải tìm kiếm ưu tiên lựa chọn tốt nhất tổng quát
Thuật giải tìm kiếm ưu tiên lựa chọn tốt nhất (best-first-search) là một dạng của tìm
kiếm có thông tin. Nó duyệt qua không gian tìm kiếm theo thứ tự ưu tiên của các
phần tử theo một quy tắc đặt trước. Judea Pearl mô tả thuật giải tìm kiếm ưu tiên
lựa chọn tốt nhất được thực hiện bởi việc ước lượng giá trị thỏa mãn lời giải của
phần tử n bởi một hàm lượng giá heuristic. Hàm lượng giá này sẽ phụ thuộc vào giá
trị của phần tử n, yêu cầu của lời giải, và những thông tin thu thập trong quá trình
duyệt trước đó và quan trọng nhất là phụ thuộc vào mọi tri thức bổ sung về miền
xác định của bài toán. Các thuật giải tìm kiếm theo lựa chọn tốt nhất thường được
sử dụng để tìm đường trong quá trình tìm kiếm tổ hợp, ví dụ như thuật giải và thuật giải tìm kiếm ∗…
Rõ ràng về mặt bản chất, thuật giải tìm kiếm ưu tiên lựa chọn tốt nhất hoàn toàn
tương thích với thuật giải tìm kiếm tổng quát đã trình bày ở Mục 5-2, chỉ khác ở
62
danh sách thứ tự chờ duyệt của các ứng viên. Để tăng hiệu quả cho việc thực thi,
danh sách chờ duyệt này sẽ được cài đặt bằng một hàng đợi ưu tiên.
Từ đó, ta có thể xây dựng lớp thuật giải tìm kiếm ưu tiên lựa chọn tốt
nhất ℎ kế thừa từ ℎ trong đó hàm hook () sẽ tạo ra một đối tượng hoạt động
theo cơ chế chọn phần tử có giá trị hàm lượng giá tốt nhất. Khi cài đặt bằng ngôn
ngữ lập trình Java, ta thể sử dụng kết hợp với một lớp Comparator
để so sánh hàm lượng giá . Comparator là lớp tổng quát biểu diễn hàm so
sánh và biểu diễn hàm lượng giá bất kì. Hai lớp này có sẵn trong STL
của C++ ( và ), khi sử dụng ta phải cài đặt lại
theo cơ chế tương tự.
Bảng 4-5 Thuật giải tìm kiếm ưu tiên lựa chọn tốt nhất
class BestFirstSearch extends SearchStrategy {
class BestFirstIterator extends SearchStrategy.Iterator {
public BestFirstIterator(SearchProblem p, Function f) {
// tạo mới hàng đợi ưu tiên với comparator theo f
}
public Object select () {
// hàm này trả về vị trí đầu tiên của hàng đợi ưu tiên
}
public void explore () {
// thêm phần tử mới vào hàng đợi và cập nhật lại thứ tự
}
}
protected Iterator createExploringList (SearchProblem p) {
return new BestFirstIterator (p, getEvalFunc() );
}
}
63
4.3.3.2 Thuật giải A*
Thuật giải A* là một thuật giải tìm kiếm có thông tin được sử dụng để tìm một
đường đi từ một phần tử khởi đầu tới một phần tử đích cho trước (hoặc tới một phần
tử thỏa mãn một điều kiện đích). Thuật giải này sử dụng một hàm lượng giá
heuristic để xếp loại từng phần tử theo ước lượng về tuyến đường tốt nhất đi qua
phần tử đó và duyệt các phần tử theo thứ tự của đánh giá heuristic này. Do đó, thuật
toán ∗ là một trường hợp của tìm kiếm ưu tiên lựa chọn tốt nhất (best-first search).
Do xác định thuật giải ∗ chính là một trường hợp của thuật giải ưu tiên lựa chọn
tốt nhất nên ta dễ dàng xây dựng lớp AStar biểu diễn thuật giải ∗ kế thừa trực tiếp
từ thuật giải best-first search.
Bảng 4-6 Thuật giải A*
class AStar extends BestFirstSearchStrategy {
protected Function getEvalFunc() {
// trả về hàm lượng giá heuristic
}
}
4.3.4 Thuật giải tìm kiếm cục bộ
4.3.4.1 Thuật giải tìm kiếm cục bộ tổng quát
Thuật giải tìm kiếm cục bộ (hoặc thuật giải tìm kiếm địa phương) là giải pháp
metaheuristic cho việc giải các bài toán tính toán tối ưu khó trong máy tính. Thuật
giải này có thể được áp dụng cho các bài toán tìm kiếm lời giải gần đúng tối ưu
trong một loạt các lời giải ứng viên. Phương pháp tìm kiếm sẽ duyệt qua các lời giải
trong không gian tìm kiếm cho đến khi lời tìm ra lời giải được cho là tối ưu hoặc
vượt quá thời gian tìm kiếm cho phép. Một số bài toán kinh điển có thể áp dụng
64
thuật giải tìm kiếm cục bộ như: bài toán người du lịch, bài toán xếp lịch trực y tá,
bài toán tìm tập phủ đỉnh của đồ thị …
Thuật giải tìm kiếm cục bộ sẽ bắt đầu từ một ứng viên lời giải, kiểm tra và liên tục
chọn sang ứng viên lời giải kế tiếp (hay ứng viên láng giềng) đến khi dừng thuật
giải. Tuy nhiên mỗi ứng viên lời giải đều có thể có hơn một lời giải láng giềng, cho
nên mỗi cách lựa chọn lời giải láng giềng trong danh sách láng giềng để thành bước
duyệt kế tiếp có thể trở thành một thuật giải khác.
Bảng 4-7 Thuật giải tìm kiếm cục bộ
abtract class LocalSearch extends SearchStrategy {
abtract class LocalSearchIterator extends
SearchStrategy.Iterator {
public Object select () {
// trả về phần tử đang chờ duyệt hoặc null
}
public void explore () {
// chọn chỉ một phần tử láng giềng làm phần tử chờ duyệt
// kế tiếp
}
}
protected Iterator createExploringList (SearchProblem p) {
return new LocalSearchIterator (p);
}
}
4.3.4.2 Thuật giải leo đồi
Thuật giải leo đồi là kỹ thuật giải bài toán theo phương pháp toán tối ưu, thuộc họ
thuật giải tìm kiếm cục bộ. Ở mỗi bước chọn phần tử kế tiếp trong thuật giải tìm
kiếm cục bộ, thuật giải leo đồi chọn phần tử có giá trị tương thích cao nhất theo một
hàm lượng giá có sẵn. Mã giả thuật giải leo đồi được thể hiện trong Bảng 4-8
65
Bảng 4-8 Mã giả thuật giải leo đồi
Hill Climbing Algorithm
currentNode = startNode;
loop do
L = NEIGHBORS(currentNode);
nextEval = -INF; = NULL;
for all x in L
if (EVAL(x) > nextEval)
nextNode = x; = EVAL(x);
if nextEval <= EVAL(currentNode)
return currentNode;
currentNode = nextNode;
Tuy nhiên, khi cài đặt thuật giải leo đồi trong khung thuật giải tìm kiếm. Ta nhận
xét rằng thuật giải leo đồi là một trường hợp của thuật giải tìm kiếm cục bộ. Do vậy
ta có thể cài đặt thuật giải leo đồi kế thừa từ thuật giải tìm kiếm cục bộ như sau:
Bảng 4-9 Thuật giải leo đồi kế thừa từ thuật giải tìm kiếm cục bộ
class HillClimbing extends LocalSearch {
abtract class HillClimbingIterator extends
SearchStrategy.Iterator {
public Object select () {
// trả về phần tử đang chờ duyệt hoặc null
}
public void explore () {
// chọn chỉ một phần tử láng giềng có giá trị tương thích
// cao nhất làm phần tử kế tiếp
}
}
protected Iterator createExploringList (SearchProblem p) {
return new HillClimbingIterator (p, getEvalFunc() );
}
}
66
4.4 Tổng kết
Như vậy qua quá trình xây dựng thuật giải tìm kiếm tổng quát và các thuật giải tìm
kiếm cụ thể giải thuật kế thừa từ lớp thuật giải tìm kiếm ℎ , ta đã
hình thành một khung thuật giải gọi là khung thuật giải dành cho các thuật giải tìm
kiếm. Mỗi thuật giải tìm kiếm cụ thể sẽ cài đặt hàm nhượng quyền lại một số hàm
của lớp thuật giải tổng quát, và quan trọng nhất là hàm select() để chọn một phần tử
và hàm explore() để cập nhật danh sách ứng viên chờ duyệt.
Thuật giải Cài đặt hàm nhượng quyền Ghi chú
Depth-First-
Search
select(): Chọn ứng viên mới đưa vào, xóa khỏi danh
sách
explore(c): Đưa vào danh sách các phần tử kề của c
Stack
Breadth-
First-Search
select(): Chọn ứng viên sớm nhất trong danh sách,
xóa khỏi danh sách
explore(c): Đưa vào danh sách các phần tử kề của c
Queue
Best-First-
Search
select(): Chọn ứng viên có giá trị lượng giá cao nhất
trong danh sách, xóa khỏi danh sách
explore(c): Đưa vào danh sách các phần tử