Tải bản đầy đủ (.doc) (17 trang)

Tiểu luận các thuật toán tìm kiếm và độ phức tạp của các thuật toán

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (348.29 KB, 17 trang )

ĐẠI HỌC HUẾ
TRƯỜNG ĐẠI HỌC KHOA HỌC
KHOA CÔNG NGHỆ THÔNG TIN

TIỂU LUẬN
Các thuật toán tìm kiếm và độ phức tạp
của các thuật toán

Giáo viên : PGS.TS Trương Công Tuấn
Cơ sở toán cho tin học
Phú Yên 2015
Mục Lục
Mục Lục 2
I. Mở đầu: 3
II. Các giải thuật tìm kiếm: 3
1. Giải thuật tìm kiếm không có thông tin 3
1.1 Tìm kiếm trên danh sách 3
1.2. Tìm kiếm trên cây 7
1.3. Tìm kiếm trên đồ thị 9
2. Tìm kiếm có thông tin: 11
2.1 Tìm kiếm tối ưu (Best First Search) 11
2.2 Thuật toán A* 13
3. Tìm kiếm đối kháng 15
3.1 Trò chơi đối kháng 15
3.2 Cây trò chơi 17
III. Tổng kết 17
Nhóm 04 Trang 2
Cơ sở toán cho tin học
I. Mở đầu:
Trong ngành khoa học máy tính, một giải thuật tìm kiếm là một thuật toán
lấy đầu vào là một bài toán và trả về kết quả là một lời giải cho bài toán đó,


thường là sau khi cân nhắc giữa một loạt các lời giải có thể.
Hầu hết các thuật toán được nghiên cứu bởi các nhà khoa học máy tính để
giải quyết các bài toán đều là các thuật toán tìm kiếm.
Tập hợp tất cả các lời giải có thể đối với một bài toán được gọi là không
gian tìm kiếm. Thuật toán thử sai (brute-force search) hay các thuật toán tìm kiếm
"sơ đẳng" không có thông tin sử dụng phương pháp đơn giản nhất và trực quan
nhất. Trong khi đó, các thuật toán tìm kiếm có thông tin sử dụng heuristics để áp
dụng các tri thức về cấu trúc của không gian tìm kiếm nhằm giảm thời gian cần
thiết cho việc tìm kiếm.
II. Các giải thuật tìm kiếm:
1. Giải thuật tìm kiếm không có thông tin
Một giải thuật tìm kiếm không có thông tin là giải thuật không tính đến bản
chất cụ thể của bài toán. Khi đó, các giải thuật 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 giải thuật 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, và một quá trình tìm kiếm (đặc biệt
tìm kiếm theo cây) sẽ cần một khoảng thời gian đáng kể cho các ví dụ nhỏ. Do đó,
để tăng tốc độ quá trình tìm kiếm, đôi khi chỉ có thể dùng giải thuật tìm kiếm có
thông tin.
1.1 Tìm kiếm trên danh sách
Có lẽ các giải thuật tìm kiếm trên danh sách là loại giải thuật 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 nào đó.
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 toán này đã được nghiên cứu kỹ càng.
1.1.1 Tìm kiếm tuyến tính(tuần tự)
 Trường hợp sử dụng:
Nhóm 04 Trang 3
Cơ sở toán cho tin học
– Dữ liệu được lưu một cách “tự nhiên”, không có xử lý đặc
biệt hoặc không được tổ chức ở một định dạng cho trước.

– Lưu trên file truy xuất tuần tự.
 Ý tưởng:
– Xét lần lượt các phần tử đang được lưu
– Với mỗi phần tử, so sánh khóa của nó với khóa cần tìm.
 Nếu bằng nhau thì báo kết quả
Xét danh sách là một mảng ta có thuật toán như sau:
Algorithm TKTuanTu(A, k)
Input: Một mảng n phần tử số A, k là khóa cần tìm
Output: vị trí khóa k trong A. Nếu không có trả về -1
For i ← 1 to n do
if (A[i] = k) then
return i
Return -1
Phân tích độ phức tạp của thuật toán:
 Trường hợp xấu nhất:
– Không có khóa cần tìm trong dãy A
– Độ phức tạp: O(n)
 Trường hợp trung bình:
– Khả năng phần tử cần tìm xuất hiện trong dãy A là n/2
– Độ phức tạp: O(n/2) = O(n)
 Khi dãy A kích thước lớn à thời gian tìm kiếm lớn
1.1.2 Tìm kiếm nhị phân:
 Trường hợp sử dụng:
– Dữ liệu đã được sắp xếp theo khóa
– Hỗ trợ truy xuất ngẫu nhiên
Nhóm 04 Trang 4
Cơ sở toán cho tin học
 Ý tưởng:
– Dựa trên tính thứ tự của các khóa loại bỏ các phần tử chắc
chắn sẽ lớn hơn hoặc nhỏ hơn khóa đang tìm.

Xét danh sách là một mảng ta có thuật toán như sau:
Algorithm TKNhiPhan(A, k)
Input: Một mảng n phần tử số A, k là khóa cần tìm
Output: vị trí khóa k trong A. Nếu không có trả về -1
dau 1
cuoi n
while (dau <= cuoi)
giua = (dau+cuoi)/2;
if a[giua] > k then
cuoi = giua – 1
else if a[giua] < k then
dau = giua + 1
else
return giua;
Return -1
Đánh giá độ phức tạp của thuật toán:
 Gọi T(n) thời gian thực thi tìm kiếm nhị phân trên dãy có độ dài
n.
 Với a là một hằng số
 Trong trường hợp xấu nhất, nghĩa là khóa cần tìm không xuất
hiện trong dãy khóa dữ liệu.
Nhóm 04 Trang 5
, 2
( )
( / 2) , 2
a n
T n
T n a n
<


=

+ ≥

2
2
3
log
2
( ) ( / 2)
( / 4) ( / 2 ) 2
( /8) 2 ( / 2 ) 3

( / 2 ) log
(log )
n
T n T n a
T n a a T n a
T n a a T n a
T n n a
O n
 
 
= +
= + + = +
= + + = +
=
= +
 
 

=
Cơ sở toán cho tin học
1.1.3 Cây nhị phân tìm kiếm:
 Ý tưởng:
– So sánh giá trị khóa cần tìm với giá trị lưu trong nút gốc
của cây.
 Nếu bằng thì trả về nút hiện tại
 Nếu nhỏ hơn thì tìm kiếm trên cây con bên trái
 Nếu lớn hơn thì tìm kiếm trên cây con bên phải
– Nếu cây rỗng thì không có giá trị cần tìm trong cây.
 Algorithm TK_NPTK(x, k)
Input: Cây NPTK đặc trưng bởi nút gốc x; k là khóa cần tìm
Output: Nút chứa giá trị khóa cần tìm. Nếu không có trả về NIL
if x=NIL or k=x->key then
return x
else
if k < x->key then
return TK_NPTK(x->left, k)
else
return TK_NPTK(x->right, k)
Đánh giá độ phức tạp của thuật toán:
 Trường hợp xấu nhất:
– độ phức tạp thuật toán tỉ lệ với đường đi dài nhất trong cây
= chiều cao của cây
– T(n) = O(h)
Nhóm 04 Trang 6
Cơ sở toán cho tin học
 Trường hợp trung bình:
– T(n) = O(logn)
1.2. Tìm kiếm trên cây

1.2.1 Thuật toán tìm kiếm theo chiều sâu(DFS)
Tư tưởng chính của thuật toán là: Giả sử chúng ta đang xét trên đồ thị
G(V,E). Từ một đỉnh u V hiện thời nào đó ta sẽ thăm tới đỉnh kề v của u và quá
trình được lặp lại đối với đỉnh v. ở bước tổng quát, giả sử hiện tại đang xét đỉnh
u0, chúng ta sẽ có hai khả năng sẽ xảy ra:
Nếu như tồn tại một đỉnh v0 kề với u0 mà chưa được thăm thì đỉnh
v0 đó sẽ trở thành đỉnh đã thăm và quá trình tìm kiếm lại bắt đầu từ đỉnh v0 đó.
Ngược lại, nếu mọi đỉnh kề với u0 đều đã thăm thì ta sẽ quay trở lại
đỉnh mà trước đó ta đến đỉnh u0 để tiếp tục quá trình tìm kiếm.
Như vậy, trong quá trình thăm đỉnh bằng thuật toán tìm kiếm theo
chiều sâu, đỉnh được thăm càng muộn càng sớm được duyệt xong (Cơ chế Last In
First Out - Vào sau ra trước). Do đó, ta có thể tổ chức quá trình này bằng một thủ
tục đệ quy như sau:
Procedure DFS(u);
Begin
Visit(u);
Daxet[u]:=True;
For v Kề(u do
if not Daxet[v] then DFS(v);
End;
Và thủ tục duyệt hệ thống toàn bộ đỉnh của đồ thị sẽ là:
Procedure Find;
Begin
Fillchar(Daxet,SizeOf(Daxet),False);
For u V do
If not Daxet[u] then DFS(u);
End;
Nhóm 04 Trang 7
Cơ sở toán cho tin học
Dễ nhận thấy rằng, mỗi lần gọi DFS(u) thì toàn bộ các đỉnh cùng thành

phần liên thông với u sẽ được viếng thăm. Thủ tục Visit(u) là thao tác trên đỉnh u
trong từng bài toán đặt ra cụ thể.
1.2.2 Thuật toán tìm kiếm theo chiều rộng(BFS)
Thuật toán này thực ra là sự cải biến về thứ tự duyệt đỉnh trên đồ thị
của tìm kiếm theo chiều sâu bằng cách thay vì dùng một STACK thì ta lại dùng
một hàng đợi QUEUE để kết nạp đỉnh được thăm. Như vậy, đỉnh được thăm càng
sớm sẽ càng sớm trở thành duyệt xong (cơ chế First In First Out - Vào trước ra
trước). Thủ tục được mô tả dưới đây:
Procedure BFS(u);
Begin
Queue:=Empty
Kết nạp u vào Queue;
Daxet[u]:=True;
While Queue<>Empty do
Begin
Lấy v từ Queue;
Visit(v);
For w Kề(v) do
If not Daxet[w] then
Begin
Kết nạp w vào Queue;
Daxet[w]:=True;
End;
End;
End;
Ta có thủ tục tìm kiếm theo chiều rộng là:
Procedure Find;
Begin
Fillchar(Daxet,SizeOf(Daxet),False);
For u V do

Nhóm 04 Trang 8
Cơ sở toán cho tin học
If not Daxet[u] then BFS(u);
End;
1.2.3 Độ phức tạp của thuật toán DFS và BFS
Quá trình tìm kiếm trên đồ thị bắt đầu từ một đỉnh có thể thăm tất cả
các đỉnh còn lại, khi đó cách biểu diễn đồ thị có ảnh hưởng lớn tới chi phí về thời
gian thực hiện giải thuật:
 Trong trường hợp ta biểu diễn đồ thị bằng danh sách kề, cả hai thuật
toán BFS và DFS đều có độ phức tạp tính toán là O(n + m) = O(max(n, m)). Đây
là cách cài đặt tốt nhất.
 Nếu ta biểu diễn đồ thị bằng ma trận kề như ở trên thì độ phức tạp
tính toán trong trường hợp này là O(n + n2) = O(n2).
 Nếu ta biểu diễn đồ thị bằng danh sách cạnh, thao tác duyệt những
đỉnh kề với đỉnh u sẽ dẫn tới việc phải duyệt qua toàn bộ danh sách cạnh, đây là
cài đặt tồi nhất, nó có độ phức tạp tính toán là O(n.m).
1.3. 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
toán tìm kiếm
1.3.1 Thuật toán Dijkstra:
Cho đơn đồ thị liên thông, có trọng số G=(V,E). Tìm khoảng cách
d(u0,v) từ một đỉnh u0 cho trước đến một đỉnh v bất kỳ của G và tìm đường đi
ngắn nhất từ u0 đến v.
Phương pháp của thuật toán Dijkstra là: xác định tuần tự đỉnh có
khoảng cách đến u0 từ nhỏ đến lớn.
Trước tiên, đỉnh có khoảng cách đến a nhỏ nhất chính là a, với
d(u0,u0)=0.
Trong các đỉnh v ≠ u0, tìm đỉnh có khoảng cách k1 đến u0 là nhỏ
nhất. Đỉnh này phải là một trong các đỉnh kề với u0. Giả sử đó là u1. Ta có:
d(u0,u1) = k1.

Trong các đỉnh v ≠ u0 và v ≠ u1, tìm đỉnh có khoảng cách k2 đến u0
là nhỏ nhất. Đỉnh này phải là một trong các đỉnh kề với u0 hoặc với u1. Giả sử đó
là u2.
Ta có: d(u0,u2) = k2.
Nhóm 04 Trang 9
Cơ sở toán cho tin học
Tiếp tục như trên, cho đến bao giờ tìm được khoảng cách từ u0 đến
mọi đỉnh v của G. Nếu V={u0, u1, , un} thì: 0 = d(u0,u0) < d(u0,u1) < d(u0,u2)
< < d(u0,un).
Thuật toán:
procedure Dijkstra (G=(V,E) là đơn đồ thị liên thông, có trọng số với
trọng số dương)
{G có các đỉnh a=u0, u1, , un=z và trọng số m(ui,uj),
với m(ui,uj) =∞ nếu (ui,uj) không là một cạnh
trong G}
for i := 1 to n
L(ui) := ∞
L(a) := 0
S := V \ {a}
u := a
while S Rỗng
begin
for tất cả các đỉnh v thuộc S
if L(u) +m(u,v) < L(v) then L(v) := L(u)+m(u,v)
u := đỉnh thuộc S có nhãn L(u) nhỏ nhất
{L(u): độ dài đường đi ngắn nhất từ a đến u}
S := S \ {u}
End
Độ phức tạp của thuật toán:
Thuật toán Dijkstra bình thường sẽ có độ phức tạp là O(n^2+m). Tuy

nhiên ta có thể sử dụng kết hợp với cấu trúc heap, khi đó độ phức tạp sẽ là
O((m+n)\log n), nếu dùng đống Fibonacci thì độ phức tạp giảm xuống còn O(m +
n\log n). Trong đó m là số cạnh, n là số đỉnh của đồ thị đang xét.
1.3.2 Thuật toán Kruskal
Thuật toán sẽ xây dựng tập cạnh ET của cây khung nhỏ nhất T=(VT,
ET) theo từng bước. Trước hết sắp xếp các cạnh của đồ thị G theo thứ tự không
giảm của trọng số.
Nhóm 04 Trang 10
Cơ sở toán cho tin học
Bắt đầu từ ET=Rỗng, ở mỗi bước ta sẽ lần lượt duyệt trong danh
sách cạnh đã sắp xếp, từ cạnh có độ dài nhỏ đến cạnh có độ dài lớn hơn, để tìm ra
cạnh mà việc bổ sung nó vào tập ET không tạo thành chu trình trong tập này.
Thuật toán sẽ kết thúc khi ta thu được tập ET gồm n-1 cạnh. Cụ thể có thể mô tả
như sau:
1. Bắt đầu từ đồ thị rỗng T có n đỉnh.
2. Sắp xếp các cạnh của G theo thứ tự không giảm của trọng số.
3. Bắt đầu từ cạnh đầu tiên của dãy này, ta cứ thêm dần các cạnh của
dãy đã được xếp vào T theo nguyên tắc cạnh thêm vào không được tạo thành chu
trình trong T
4. Lặp lại Bước 3 cho đến khi nào số cạnh trong T bằng n-1, ta thu
được cây khung nhỏ nhất cần tìm
2. Tìm kiếm có thông tin:
2.1 Tìm kiếm tối ưu (Best First Search)
Mổ tả thuật toán:
Tại mỗi bước của tìm kiếm BFS, ta chọn đi theo trạng thái có khả
năng cao nhất trong số các trạng thái đã được xét cho đến thời điểm đó. Như vậy,
với tiếp cận này, ta sẽ ưu tiên đi vào những nhánh tìm kiếm có khả năng nhất,
nhưng ta sẽ không bị lẩn quẩn trong các nhánh này vì nếu càng đi sâu vào một
hướng mà ta phát hiện ra rằng hướng này càng đi thì càng tệ, đến mức nó xấu hơn
cả những hướng mà ta chưa đi, thì ta sẽ không đi tiếp hướng hiện tại nữa mà chọn

đi theo một hướng tốt nhất trong số những hướng chưa đi. Đó là tư tưởng chủ đạo
của tìm kiếm BFS. Ví dụ minh họa:
Nhóm 04 Trang 11
Cơ sở toán cho tin học
Hình Minh họa thuật giải Best-First Search
Khởi đầu, chỉ có một nút (trạng thái) A nên nó sẽ được mở rộng tạo
ra 3 nút mới B,C và D. Các con số dưới nút là giá trị cho biết độ tốt của nút. Con
số càng nhỏ, nút càng tốt. Do D là nút có khả năng nhất nên nó sẽ được mở rộng
tiếp sau nút A và sinh ra 2 nút kế tiếp là E và F. Đến đây, ta lại thấy nút B có vẻ có
khả năng nhất (trong các nút B,C,E,F) nên ta sẽ chọn mở rộng nút B và tạo ra 2
nút G và H. Nhưng lại một lần nữa, hai nút G, H này được đánh giá ít khả năng
hơn E, vì thế sự chú ý lại trở về E. E được mở rộng và các nút được sinh ra từ E là
I và J. Ở bước kế tiếp, J sẽ được mở rộng vì nó có khả năng nhất. Quá trình này
tiếp tục cho đến khi tìm thấy một lời giải.
Lưu ý rằng tìm kiếm này rất giống với tìm kiếm leo đồi dốc đứng,
với 2 ngoại lệ. Trong leo núi, một trạng thái được chọn và tất cả các trạng thái
khác bị loại bỏ, không bao giờ chúng được xem xét lại. Cách xử lý dứt khoát này
là một đặc trưng của leo đồi. Trong BFS, tại một bước, cũng có một di chuyển
được chọn nhưng những cái khác vẫn được giữ lại, để ta có thể trở lại xét sau đó
khi trạng thái hiện tại trở nên kém khả năng hơn những trạng thái đã được lưu trữ.
Hơn nữa, ta chọn trạng thái tốt nhất mà không quan tâm đến nó có tốt hơn hay
không các trạng thái trước đó. Điều này tương phản với leo đồi vì leo đồi sẽ dừng
nếu không có trạng thái tiếp theo nào tốt hơn trạng thái hiện hành.
Để cài đặt các thuật giải theo kiểu tìm kiếm BFS, người ta thường
cần dùng 2 tập hợp sau :
OPEN : tập chứa các trạng thái đã được sinh ra nhưng chưa được xét
đến (vì ta đã chọn một trạng thái khác). Thực ra, OPEN là một loại hàng đợi ưu
tiên (priority queue) mà trong đó, phần tử có độ ưu tiên cao nhất là phần tử tốt
Nhóm 04 Trang 12
Cơ sở toán cho tin học

nhất. Người ta thường cài đặt hàng đợi ưu tiên bằng Heap. Các bạn có thể tham
khảo thêm trong các tài liệu về Cấu trúc dữ liệu về loại dữ liệu này.
CLOSE : tập chứa các trạng thái đã được xét đến. Chúng ta cần lưu
trữ những trạng thái này trong bộ nhớ để đề phòng trường hợp khi một trạng thái
mới được tạo ra lại trùng với một trạng thái mà ta đã xét đến trước đó. Trong
trường hợp không gian tìm kiếm có dạng cây thì không cần dùng tập này.
Thuật giải BEST-FIRST SEARCH
1. Đặt OPEN chứa trạng thái khởi đầu.
2. Cho đến khi tìm được trạng thái đích hoặc không còn nút nào
trong OPEN, thực hiện :
2.a. Chọn trạng thái tốt nhất (Tmax) trong OPEN (và xóa Tmax
khỏi OPEN)
2.b. Nếu Tmax là trạng thái kết thúc thì thoát.
2.c. Ngược lại, tạo ra các trạng thái kế tiếp Tk có thể có từ trạng
thái Tmax. Đối với mỗi trạng thái kế tiếp Tk thực hiện :
Tính f(Tk); Thêm Tk vào OPEN
BFS khá đơn giản. Tuy vậy, trên thực tế, cũng như tìm kiếm chiều sâu và
chiều rộng, hiếm khi ta dùng BFS một cách trực tiếp.
2.2 Thuật toán A*
Mô tả thuật toán:
A* lưu giữ một tập các lời giải chưa hoàn chỉnh, nghĩa là các đường
đi qua đồ thị, bắt đầu từ nút xuất phát. Tập lời giải này được lưu trong một hàng
đợi ưu tiên (priority queue). Thứ tự ưu tiên gán cho một đường đi x được quyết
định bởi hàm f(x) = g(x) + h(x).
Trong đó, g(x) là chi phí của đường đi cho đến thời điểm hiện tại,
nghĩa là tổng trọng số của các cạnh đã đi qua. h(x) là hàm đánh giá heuristic về
chi phí nhỏ nhất để đến đích từ x. Ví dụ, nếu "chi phí" được tính là khoảng cách
đã đi qua, khoảng cách đường chim bay giữa hai điểm trên một bản đồ là một
đánh giá heuristic cho khoảng cách còn phải đi tiếp.
Hàm f(x) có giá trị càng thấp thì độ ưu tiên của x càng cao (do đó có

thể sử dụng một cấu trúc heap tối thiểu để cài đặt hàng đợi ưu tiên này)
Thuật toán:
function A*(điểm_xuất_phát,đích)
Nhóm 04 Trang 13
Cơ sở toán cho tin học
var đóng:= tập rỗng
var q:= tạo_hàng_đợi(tạo_đường_đi(điểm_xuất_phát))
while q không phải tập rỗng
var p:= lấy_phần_tử_đầu_tiên(q)
var x:= nút cuối cùng của p
if x in đóng
continue
if x = đích
return p
bổ sung x vào tập đóng
foreach y in các_đường_đi_tiếp_theo(p)
đưa_vào_hàng_đợi(q, y)
return failure
Trong đó, các_đường_đi_tiếp_theo(p) trả về tập hợp các đường đi tạo
bởi việc kéo dài p thêm một nút kề cạnh. Giả thiết rằng hàng đợi được sắp xếp tự
động bởi giá trị của hàm f.
"Tập hợp đóng" (đóng) lưu giữ tất cả các nút cuối cùng của p (các
nút mà các đường đi mới đã được mở rộng tại đó) để tránh việc lặp lại các chu
trình (việc này cho ra thuật toán tìm kiếm theo đồ thị). Đôi khi hàng đợi được gọi
một cách tương ứng là "tập mở". Tập đóng có thể được bỏ qua (ta thu được thuật
toán tìm kiếm theo cây) nếu ta đảm bảo được rằng tồn tại một lời giải hoặc nếu
hàm các_đường_đi_tiếp_theo được chỉnh để loại bỏ các chu trình.
Độ phức tạp thuật toán:
Độ phức tạp thời gian của A* phụ thuộc vào đánh giá heuristic.
Trong trường hợp xấu nhất, số nút được mở rộng theo hàm mũ của độ dài lời giải,

nhưng nó sẽ là hàm đa thức khi hàm heuristic h thỏa mãn điều kiện sau:
|h(x) - h*(x)| ≤ O(log h*(x))
Trong đó h* là heuristic tối ưu, nghĩa là hàm cho kết quả là chi phí
chính xác để đi từ x tới đích. Nói cách khác, sai số của h không nên tăng nhanh
hơn lôgarit của "heuristic hoàn hảo" h* - hàm trả về khoảng cách thực từ x tới
đích.
Nhóm 04 Trang 14
Cơ sở toán cho tin học
3. Tìm kiếm đối kháng
Tìm kiếm đối kháng còn gọi là tìm kiếm có đối thủ là chiến lược tìm kiếm
được áp dụng để tìm ra nước đi cho người chơi trong các trò chơi đối kháng. Chơi
cờ có thể xem như vấn đề tìm kiếm trong không gian trạng thái. Sau đây chúng ta
sẽ xem thế nào trò chơi đối kháng và chiến lược tìm kiếm nào sẽ được áp dụng.
3.1 Trò chơi đối kháng
Trong các trò chơi đấu trí như các trò chơi cờ Vua, cờ Tướng, cờ vây, cờ
caro (go-moku), 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ả. Các trò chơi này còn gọi là
các trò chơi đối kháng, diễn ra giữa hai đấu thủ. Nói chung, các trò chơi đó đều có
thể chuyển về một dạng bài toán tìm kiếm đặc biệt: tìm đường đi đến các điểm
cao nhất giữa hai đấu thủ. Trong trò chơi này phải tính đến mọi nước đi mà đối
thủ của ta có thể sử dụng.
Đặc điểm của các trò chơi trên như sau:
- Có hai đấu thủ, mỗi người chỉ đi một nước khi tới lượt.
- Các đấu thủ đều biết mọi thông tin về tình trạng trận đấu.
- Trận đấu không kéo dài vô tận, phải diễn ra hòa, hoặc một bên thắng và
bên kia thua.
Thông thường các trò chơi này hay được gọi là các loại cờ, đôi khi còn
được gọi là các trò chơi Minimax
Thuật toán Minimax:

Xét một trò chơi đối kháng trong đó hai người thay phiên nhau đi nước của
mình như cờ vua, cờ tướng, cờ carô, Trò chơi có một trạng thái bắt đầu và mỗi
nước đi sẽ biến đổi trạng thái hiện hành thành một trạng thái mới. Trò chơi sẽ kết
thúc theo một quy định nào đó, theo đó thì cuộc chơi sẽ dẫn đến một trạng thái
phản ánh có một người thắng cuộc hoặc một trạng thái mà cả hai đấu thủ không
thể phát triển được nước đi của mình, ta gọi nó là trạng thái hòa cờ. Ta tìm cách
phân tích xem từ một trạng thái nào đó sẽ dẫn đến đấu thủ nào sẽ thắng với điều
kiện cả hai đấu thủ đều có trình độ như nhau.
Ý tưởng:
Hai đối thủ trong một trò chơi được gọi là MIN và MAX. MAX đại diện
cho đối thủ quyết giành thắng lợi hay cố gắng tối đa hóa ưu thế của mình. Ngược
lại MIN là đối thủ cố gắng tối thiểu hóa điểm số của MAX. Ta giả thiết MIN cũng
dùng cùng những thông tin như MAX.
Nhóm 04 Trang 15
Cơ sở toán cho tin học
Một trò chơi như vậy có thể được biểu diễn bởi một cây trò chơi. Mỗi một
nút của cây biểu diễn cho một trạng thái. Nút gốc biểu diễn cho trạng thái bắt đầu
của cuộc chơi. Mỗi nút lá biểu diễn cho một trạng thái kết thúc của trò chơi (trạng
thái thắng, thua hoặc hòa). Nếu trạng thái x được biểu diễn bởi nút n thì các con
của n biểu diễn cho tất cả các trạng thái kết quả của các nước đi có thể xuất phát
từ trạng thái x. Do hai đấu thủ luân phiên nhau đi nước của mình nên các mức
(lớp) trên cây trò chơi cũng luân phiên nhau là MAX và MIN. Cây trò chơi vì thế
còn có tên là cây MIN-MAX. Trên cây trò chơi các nút ứng với trạng thái mà từ
đó người chơi MAX chọn nước đi sẽ thuộc lớp MAX, các nút ứng với trạng thái
mà từ đó người chơi MIN chọn nước đi sẽ thuộc lớp MIN. Chiến lược minimax
thể hiện qua quy tắc định trị cho các nút trên cây trò chơi như sau:
- Nếu nút là nút lá gán cho nút đó một giá trị để phản ánh trạng thái thắng
thua hay hòa của các đấu thủ.
- Sử dụng giá trị của các nút lá để xác định giá trị của các nút ở các mức
trên trong cây trò chơi theo quy tắc:

+ Nút thuộc lớp MAX thì gán cho nó giá trị lớn nhất của các nút con của
nút đó.
+ Nút thuộc lớp MIN thì gán cho nó giá trị nhỏ nhất của các nút con của nút
đó.
Giá trị được gán cho từng trạng thái theo quy tắc trên chỉ rõ giá trị của trạng
thái tốt nhất mà mỗi đối thủ có thể hy vọng đạt được. Người chơi sẽ sử dụng các
giá trị này để lựa chọn các nước đi cho mình. Đối với người chơi MAX khi đến
lượt đi, người chơi này sẽ chọn nước đi ứng với trạng thái có giá trị cao nhất trong
các trạng thái con, còn với người chơi MIN khi đến lượt sẽ chọn nước đi ứng với
trạng thái có giá trị nhỏ nhất trong các trạng thái con.
Độ phức tạp:
Thuật toán Minimax thăm toàn bộ cây trò chơi bằng việc dùng chiến lược
tìm kiếm theo chiều sâu. Nên độ phức tạp của thuật toán này tương ứng trực tiếp
với kích thước không gian tìm kiếm bd, trong đó b là hệ số phân nhánh của cây
hay chính là nước đi hợp pháp tại mỗi điểm, d là độ sâu tối đa của cây. Thuật toán
sẽ thăm tất cả các nút không chỉ là các nút lá vì vậy số lượng các nút được thăm
sẽ là b(bd-1)/(b-1). Nhưng hàm lượng giá sẽ là phương thức chi phối hầu hết thời
gian và chỉ làm việc trên các nút lá, vì vậy việc thăm các nút không phải các nút lá
có thể bỏ qua . Do đó độ phức tạp thời gian là O(bd). Bản chất của thuật toán là
tìm kiếm theo chiều sâu, vì vậy việc đòi hỏi không gian bộ nhớ của nó chỉ tuyến
tính với d và b.
Nhóm 04 Trang 16
Cơ sở toán cho tin học
3.2 Cây trò chơi
Các trạng thái bàn cờ khác nhau (hay còn gọi là một thế cờ, tình huống cờ)
trong quá trình chơi có thể biểu diễn thành một cây tìm kiếm và ta sẽ tiến hành
tìm kiếm trên cây để tìm được nước đi tốt nhất. Cây trò chơi có các nút là các tình
huống khác nhau của bàn cờ, các nhánh nối giữa các nút sẽ cho biết từ một tình
huống bàn cờ chuyển sang tình huống khác thông qua chỉ một nước đi đơn nào
đó. Tuy nhiên, các nước đi này diễn ra theo cặp do hai đấu thủ lần lượt tiến hành.

Độ sâu của cây trò chơi là số tầng của cây. Thuật ngữ “nước đi” được thống nhất
là một lần đi của một đấu thủ hoặc một lần đi phản ứng lại của đối thủ bên kia.
Chú ý điều này khác với thói quen dùng trong thực tế một nước đi bao gồm lần đi
của ta và một lần đi của đối thủ. Nói cách khác, nước đi ở đây thực chất chỉ là
"nửa nước" theo cách hiểu của làng cờ.
Tóm lại: Cây trò chơi dùng các nút để thể hiện trạng thái của trò chơi. Cây
này là một dạng của cây ngữ nghĩa, có các nhánh ứng với việc chuyển cấu hình
sau một nước đi. Có thể xem hai nhánh xuất phát từ một nút là hai quyết định của
hai đấu thủ.
Gọi p là số mức của cây thì độ sâu của cây là d= p-1. Mỗi lựa chọn hay bước
chuyển là một nước đi
Ngoài ra còn có các giải thuật tìm kiếm khác…
III. Tổng kết
Nhóm đã Tìm hiểu tổng quan về vấn đề tìm kiếm trong đó có phát biểu bài
toán tìm kiếm và giới thiệu các kỹ thuật tìm kiếm cơ bản như tìm kiếm không có
thông tin, tìm kiếm có thông tin và tìm kiếm đối kháng và độ phức tạp của các
giải thuật.
Mặc dù có nhiều cố gắng nhưng chắc chắn rằng các kết quả đạt được không
tránh khỏi những thiếu sót và hạn chế, hy vọng rằng trong tương lai vấn đề này sẽ
được nghiên cứu sâu hơn và phát triển tốt hơn.
Nhóm 04 Trang 17
Trạng thái bàn cờ gốc (ply=0)
Lượt “ta” đi
Trạng thái bàn cờ mới (ply=1)
Lượt đối phương đi
Trạng thái bàn cờ mới (ply=2)

×