Tải bản đầy đủ (.pdf) (67 trang)

Tìm kiếm thông tin dựa vào cấu trúc dữ liệu heap

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 (847.87 KB, 67 trang )

i

LỜI CAM ĐOAN
Tôi xin cam đoan luận văn này của tự bản thân tôi tìm hiểu, nghiên
cứu. Các tài liệu tham khảo được trích dẫn và chú thích đầy đủ. Nếu không
đúng tôi xin hoàn toàn chịu trách nhiệm.
Tác giả luận văn

Nguyễn Đặng Phú


ii

LỜI CẢM ƠN
Lời đầu tiên tôi xin được bày tỏ lòng biết ơn chân thành đến Ban Giám
Hiệu, các thầy giáo, cô giáo phòng Sau đại học trường Đại học Công Nghệ
Thông Tin & Truyền Thông, các thầy giáo ở Viện Công Nghệ Thông Tin đã
giảng dạy và tạo mọi điều kiện cho tôi học tập, nghiên cứu và hoàn thành luận
văn này.
Đặc biệt, tôi xin bày tỏ sự kính trọng và lòng biết ơn sâu sắc đến TS.
Bùi Văn Thanh, người đã tận tình hướng dẫn và giúp đỡ tôi trong suốt quá
trình học tập, nghiên cứu và hoàn thành luận văn.
Tôi chân thành cảm ơn các thầy cô tổ Tin học, trường Trung học phổ
thông chuyên Lam Sơn, Thanh Hóa, nơi tôi công tác đã tạo điều kiện và hỗ
trợ tôi trong suốt thời gian qua.
Tôi cũng xin chân thành cảm ơn người thân, bạn bè đã giúp đỡ và động
viên tôi trong suốt thời gian học tập cũng như trong thời gian thực hiện luận
văn.
Xin chân thành cảm ơn!
Thanh Hóa, ngày 03 tháng 10 năm 2015



iii

MỤC LỤC

Lời cam đoan........................................................................................................... i
Lời cảm ơn ............................................................................................................. ii
Mục lục.................................................................................................................. iii
Danh mục các bảng ................................................................................................ v
Danh mục các hình ................................................................................................ vi
MỞ ĐẦU ..........................................................................................................................1

1. Lý do chọn đề tài...................................................................................... 1
2. Đối tượng và phạm vi nghiên cứu ............................................................ 2
3. Những nội dung nghiên cứu chính ........................................................... 2
4. Phương pháp nghiên cứu .......................................................................... 3
5. Ý nghĩa khoa học của đề tài ..................................................................... 3
Chương 1. KHÁI QUÁT VỀ TÌM KIẾM VÀ VẤN ĐỀ TỔ CHỨC DỮ LIỆU ......4

1.1. Khái quát về tìm kiếm ............................................................................ 4
1.1.1 Thông tin ......................................................................................... 4
1.1.2. Một số loại tìm kiếm thông tin .......................................................... 7
1.1.2.1. Tìm kiếm trên danh sách ............................................................ 7
1.1.2.3. Tìm kiếm đường đi................................................................... 11
1.2. Tổ chức dữ liệu trong tìm kiếm thông tin............................................... 13
1.2.1. Giới thiệu....................................................................................... 13
1.2.2. Một số cấu trúc dữ liệu ................................................................. 15
1.2.2.1. Stack ....................................................................................... 15
1.2.2.2. Queue ..................................................................................... 15
1.2.2.4. Heap ....................................................................................... 16

Chương 2. MỘT SỐ THUẬT TOÁN THAO TÁC TRONG HEAP ......................18

2.1. Biểu diễn Heap..................................................................................... 18


iv

2.2. Khởi tạo Heap rỗng .............................................................................. 19
2.3. UpHeap ............................................................................................... 19
2.4. DownHeap ........................................................................................... 27
2.5. Thêm một phần tử vào Heap ................................................................. 36
2.6. Đọc một phần tử đỉnh Heap .................................................................. 37
2.7. Lấy một phần tử ở gốc khỏi Heap ......................................................... 38
2.8. Cập nhật một phần tử trong Heap .......................................................... 40
2.9. Tìm kiếm đường đi theo lựa chọn tốt nhất ............................................. 42
Chương 3. XÂY DỰNG CHƯƠNG TRÌNH TÌM ĐƯỜNG ĐI TRONG THÀNH
PHỐ THANH HÓA ......................................................................................................46

3.1. Phân tích yêu cầu bài toán..................................................................... 46
3.2. Phân tích, lựa chọn công cụ .................................................................. 48
3.2.1. Mô tả dữ liệu.................................................................................. 48
3.2.2 Thiết kế các bước thực hiện ............................................................. 48
3.2.3. Ngôn ngữ lập trình ......................................................................... 51
3.3. Một số kết quả chương trình ................................................................. 51
KẾT LUẬN....................................................................................................................55
TÀI LIỆU THAM KHẢO ...........................................................................................56


v


DANH MỤC CÁC BẢNG
Trang
Bảng 2.1. Biểu diễn Heap bằng mảng 1 chiều .............................................. 18
Bảng 2.2. Bảng kết quả tính toán theo thuật toán .......................................... 44
Bảng 3.1. Trọng số các cạnh của đồ thị ........................................................ 49


vi

DANH MỤC CÁC HÌNH
Trang
Hình 1.1. Thông tin dạng văn bản .................................................................. 5
Hình 1.2. Thông tin dạng hình ảnh ................................................................. 6
Hình 1.3. Thông tin dạng âm thanh ................................................................ 6
Hình 1.4. Mô hình Stack trong thực tế.......................................................... 15
Hình 1.5. Mô hình Queue trong thực tế ........................................................ 16
Hình 1.6. Heap Max chứa các phần tử có thể giống nhau ............................. 17
Hình 2.1. Chỉ số con trái và con phải một nút trong Heap ............................ 18
Hình 2.2. Heap Max trong quá trình UpHeap ............................................... 20
Hình 2.3. Vị trí cần UpHeap ......................................................................... 21
Hình 2.4. Gán giá trị Heap[9] = 7 ................................................................. 21
Hình 2.5. Gán giá trị Heap[4] = 8 ................................................................. 22
Hình 2.6. Gán giá trị Heap[2] = 9 và kết thúc ............................................... 22
Hình 2.7. Sơ đồ thuật toán UpHeap .............................................................. 23
Hình 2.8. Đổi chỗ 2 giá trị Heap[9] và Heap[4] cho nhau ............................. 25
Hình 2.9. Đổi chỗ 2 giá trị Heap[4] và Heap[2] cho nhau ............................. 25
Hình 2.10. Sơ đồ thuật toán UpHeap dùng đệ qui ......................................... 26
Hình 2.11. Heap Max trong quá trình UpHeap ............................................. 28
Hình 2.12. Heap[1] bị thay đổi giá trị ........................................................... 28
Hình 2.13. Gán giá trị mới cho Heap[1] ....................................................... 29

Hình 2.14. Gán giá trị mới cho Heap[2] ....................................................... 29


vii

Hình 2.15. Gán giá trị mới cho Heap[4] ....................................................... 30
Hình 2.16. Gán giá trị mới cho Heap[9] ....................................................... 30
Hình 2.17. Sơ đồ thuật toán DownHeap ....................................................... 31
Hình 2.18. Heap[1] bị thay đổi giá trị trong UpHeap đệ qui ......................... 33
Hình 2.19. Đổi chỗ Heap[2] và Heap[1] cho nhau ........................................ 33
Hình 2.20. Đổi chỗ Heap[4] và Heap[2] cho nhau ........................................ 34
Hình 2.21. Đổi chỗ Heap[9] và Heap[4] cho nhau ........................................ 34
Hình 2.22. Sơ đồ thuật toán DownHeap dùng đệ quy ................................... 35
Hình 2.23. Sơ đồ thuật toán thêm một phần tử vào Heap .............................. 37
Hình 2.24. Sơ đồ thuật toán đọc một phần tử ở đỉnh Heap............................ 38
Hình 2.25 Sơ đồ thuật toán lấy một phần tử ở đỉnh Heap ............................. 39
Hình 2.26. Cập nhật Heap ............................................................................ 40
Hình 2.27. Sơ đồ khối thuật toán cập nhật một phần tử trong Heap .............. 41
Hình 2.28. Minh họa đường đi ..................................................................... 43
Hình 3.1. Bản đồ giao thông thành phố Thanh Hóa ...................................... 47
Hình 3.2. Một vùng bản đồ giao thông của thành phố Thanh Hóa ................ 49


1

MỞ ĐẦU
1. Lý do chọn đề tài
Hiện nay, công nghệ thông tin với tốc độ phát triển rất nhanh. Các nhà
khoa học khẳng định rằng chưa có một ngành khoa học – công nghệ nào lại
có nhiều ứng dụng rộng rãi như công nghệ thông tin. Việc ứng dụng công

nghệ thông tin trong giáo dục đã trở thành mối ưu tiên hàng đầu của nhiều
quốc gia, trong đó có Việt Nam. Sự tiến bộ về công nghệ và sự phổ cập của
các hệ thống phần mềm tiên tiến đã đưa đến những sự thay đổi cách đào tạo
chuyên gia trong lĩnh vực tin học. Các kiến thức giải thuật được coi là đỉnh
cao trước đây bây giờ đã trở thành “bảng cửu chương” mà ai cũng phải biết
và phải thuộc. Những giải thuật ít dùng và phức tạp thì không nhất thiết phải
biết hoặc nhớ vì bất cứ ai và lúc nào cũng có thể tra cứu, tìm kiếm chúng trên
internet khi cần thiết. Thử thách bây giờ là ở chỗ ta có thể tìm ra những giải
pháp hữu hiệu giải quyết một cách có hiệu quả các bài toán, các vấn đề có mô
hình toán học đơn giản nhưng có kích thước lớn hay không?
Để đạt được mục đích đó, người lập trình phải tận dụng tối đa khả năng
mà phần cứng và hệ điều hành cung cấp, khai thác tối đa khả năng của công
cụ lập trình, sử dụng linh hoạt các cấu trúc dữ liệu. Trong đó, Heap là một cấu
trúc dữ liệu quan trọng, có nhiều ứng dụng trong tính toán, truy vấn cơ sở dữ
liệu và xử lí tín hiệu. Bên cạnh đó, việc tìm kiếm đường đi tối ưu bằng các
phương pháp của khoa học tính toán với nguồn dữ liệu khổng lồ để cho ra kết
quả nhanh và chính xác nhất.
Trong khuôn khổ luận văn thạc sĩ, tôi chọn đề tài nghiên cứu: “Tìm
kiếm thông tin dựa vào cấu trúc dữ liệu Heap”, nghiên cứu về Heap và thực
hiện một phương pháp tiếp cận mới, nhanh chóng và linh hoạt để tìm đường
đi tối ưu trong thành phố Thanh Hóa.


2

2. Đối tượng và phạm vi nghiên cứu
Đối tượng và phạm vi nghiên cứu của luận văn tập trung vào tìm hiểu
về Heap và từ đó xây dựng ứng dụng tìm đường đi trong thành phố thành phố
Thanh Hóa.
3. Những nội dung nghiên cứu chính

Chương 1. Khái quát về tìm kiếm và vấn đề tổ chức dữ liệu
Trong ngành khoa học máy tính 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.
Vấn đề tổ chức dữ liệu là công việc hết sức quan trọng, khi ta có một
thuật toán tốt và chọn lựa cấu trúc dữ liệu phù hợp để lưu trữ thì bài toán được
giải quyết một cách nhanh chóng. Đôi khi một bài toán có thuật toán tốt
nhưng chúng ta lại chọn lựa cấu trúc dữ liệu không phù hợp thì có thể dẫn đến
việc giải quyết bài toán đó trở nên khó khăn và phức tạp hơn.
Chương 2. Một số thuật toán thao tác trong Heap
Khi làm việc với Heap, thì trên Heap có một số thao tác nhưng nó có hai
thao tác rất quan trọng là DownHeap và UpHeap.
Chương 3. Xây dựng chương trình tìm đường đi trong thành phố
Thanh Hóa
Đây là chương trình ứng dụng tìm đường đi ngắn nhất giữa hai địa điểm
bất kỳ trong thành phố Thanh Hóa. Nó giúp người sử dụng chọn nhanh và chính
xác được đường đi tối ưu nhất.


3

4. Phương pháp nghiên cứu
 Phương pháp nghiên cứu lí thuyết: Tổng hợp tài liệu, suy diễn, quy
nạp, các phương pháp hình thức,...
 Phương pháp thực nghiệm: xử lí thống kê, đối sánh,...
 Phương pháp trao đổi khoa học, tổng hợp các kết quả của các nhà
nghiên cứu liên quan đến lĩnh vực nghiên cứu, lấy ý kiến chuyên gia.
5. Ý nghĩa khoa học của đề tài

Đề tài đưa ra một phương pháp nhanh chóng, hiệu quả và linh hoạt để
tìm Min, Max trong một tập hợp động. Điều này mang ý nghĩa thiết thực
trong việc hỗ trợ tìm đường đi tối ưu trong thành phố Thanh Hóa.


4

Chương 1
KHÁI QUÁT VỀ TÌM KIẾM VÀ VẤN ĐỀ TỔ CHỨC DỮ LIỆU
1.1. Khái quát về tìm kiếm
1.1.1 Thông tin
Thông tin là những hiểu biết có thể có được về một thực thể nào đó.
Muốn đưa thông tin vào máy tính, con người phải tìm cách biểu diễn thông
tin sao cho máy tính có thể nhận biết và xử lí được. Trong tin học, dữ liệu là
thông tin đã được đưa vào máy tính.
Ta không chỉ dừng lại ở một quan niệm định tính về thông tin như trên
mà còn cho thông tin một quan niệm định lượng. Mỗi sự vật hay sự kiện đều
hàm chứa một lượng thông tin.
Muốn nhận biết một đối tượng nào đó, ta phải biết đủ lượng thông tin
về nó. Tương tự, để máy nhận biết một đối tượng nào đó, ta cũng phải cung
cấp cho máy đủ lượng thông tin về đối tượng này.
Đơn vị cơ bản đo lường thông tin là bit. Đó là lượng thông tin vừa đủ
để xác định chắc chắn một trạng thái của một sự kiện có hai trạng thái với khả
năng xuất hiện như nhau.
Ví dụ, xét việc tung ngẫu nhiên đồng xu có hai mặt hoàn toàn cân xứng
với khả năng xuất hiện của mỗi mặt là như nhau. Nếu kí hiệu một mặt của
đồng xu là 1 và mặt kia là 0 thì sự xuất hiện kí hiệu 1 hay 0 sau khi tung đồng
xu cho ta một lượng thông tin là 1 bit.
Trong tin học, thuật ngữ bit thường dùng để chỉ phần nhỏ nhất của bộ
nhớ máy tính để lưu trữ một trong hai kí hiệu, được sử dụng để biểu diễn

thông tin trong máy tính, là 0 và 1.


5

Thế giới quanh ta rất đa dạng nên có nhiều dạng thông tin khác nhau và
mỗi dạng có một số cách thể hiện khác nhau. Có thể phân loại thông tin
thành: loại số (số nguyên, số thực, ...) và loại phi số (văn bản, hình ảnh, âm
thanh, ...). Dưới đây là một số dạng thông tin loại phi số thường gặp trong
cuộc sống:
Dạng văn bản: Là dạng quen thuộc nhất và thường gặp trên các phương
tiện mang thông tin như: tờ báo, cuốn sách, vở ghi bài, tấm bia, ...

Hình 1.1. Thông tin dạng văn bản
Dạng hình ảnh: bức tranh vẽ, bức ảnh chụp, bản đồ, băng hình ... là những
phương tiện mang thông tin dạng hình ảnh.


6

Hình 1.2. Thông tin dạng hình ảnh
Dạng âm thanh: Tiếng nói con người, tiếng sóng biển, tiếng đàn, tiếng
chim hót, … là thông tin dạng âm thanh. Băng từ, đĩa từ,… có thể dùng làm vật
chứa thông tin dạng âm thanh.

Hình 1.3. Thông tin dạng âm thanh


7


Với dự phát triển của khoa học - kĩ thuật, trong tương lai con người sẽ có
khả năng thu thập, lưu trữ và xử lí các dạng thông tin mới khác.
1.1.2. Một số loại tìm kiếm thông tin
Trong ngành khoa học máy tính 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.
1.1.2.1. Tìm kiếm trên danh sách
Đây có lẽ là loại tìm kiếm cơ bản nhất. Mục đích là tìm kiếm theo một
tiêu chí nào đó của một danh sách và đưa ra kết quả những phần tử của danh
sách thỏa mãn tiêu chí đó hay không. Trong loại tìm kiếm này, chúng ta có các
dạng tìm kiếm cơ bản sau: tìm kiếm tuần tự và tìm kiếm nhị phân và phép băm.
Thuật toán đơn giản nhất là tìm kiếm tuần tự, là một phương pháp tìm
kiếm một phần tử cho trước trong một danh sách bằng cách duyệt lần lượt
từng phần tử của danh sách đó cho đến lúc tìm thấy giá trị mong muốn hay đã
duyệt qua toàn bộ danh sách. Thuật toán này kiểm tra từng phần tử trong danh
sách theo thứ tự của danh sách đó. Giải thuật này tỏ ra khá hiệu quả khi cần
tìm kiếm trên một danh sách đủ nhỏ hoặc một danh sách chưa sắp thứ tự.
Nhưng nếu danh sách lớn, nó có thời gian chạy khá lớn: O(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 toán cao cấp hơn với thời gian chạy là
hàm logarit. Đối với các danh sách lớn, thuật toán này tốt hơn hẳn tìm kiếm
tuần tự, nhưng nó đòi hỏi danh sách phải được sắp xếp từ trước. Trong mỗi
bước, so sánh phần tử cần tìm với phần tử nằm ở chính giữa danh sách. Nếu


8


hai phần tử bằng nhau thì phép tìm kiếm thành công và thuật toán kết thúc.
Nếu chúng không bằng nhau thì tùy vào phần tử nào lớn hơn, thuật toán lặp
lại bước so sánh trên với nửa đầu hoặc nửa sau của danh sách. Vì số lượng
phần tử trong danh sách cần xem xét giảm đi một nửa sau mỗi bước, nên thời
gian thực thi của thuật toán là O(logn).
Phép băm cũng được dùng cho tìm kiếm trên danh sách. Tư tưởng của
phép băm là dựa vào giá trị của các khóa, chia các khóa đó ra thành các
nhóm. Những khóa thuộc cùng một nhóm có một đặc điểm chung và đặc
điểm này không có trong các nhóm khác. Khi có một khóa tìm kiếm X, trước
hết ta xác định xem nếu X thuộc vào dãy khóa đã cho thì nó phải thuộc nhóm
nào và tiến hành tìm kiếm trên nhóm đó. Một ví dụ là trong cuốn từ điển, các
bạn sinh viên thường dán vào 26 mảnh giấy nhỏ vào các trang để đánh dấu
trang nào là trang khởi đầu của một đoạn chứa các từ có cùng chữ cái đầu. Để
khi tra từ chỉ cần tìm trong các trang chứa những từ có cùng chữ cái đầu với
từ cần tìm. Có nhiều cách cài đặt phép băm:
 Các thứ nhất là chia dãy khóa làm các đoạn, mỗi đoạn chứa những
khóa thuộc cùng một nhóm và ghi nhận lại vị trí các đoạn đó. Để khi có
khóa tìm kiếm, có thể xác định được ngay cần phải tìm khóa đó trong
đoạn nào.
 Cách thứ hai là chia dãy khóa làm m nhóm, mỗi nhóm là một danh
sách nối đơn chứa các giá trị khóa và ghi nhận lại chốt của mỗi danh
sách nối đơn. Với một khóa tìm kiếm, ta xác định được phải tìm khóa
đó trong danh sách nối đơn nào và tiến hành tìm kiếm tuần tự trên danh
sách nối đơn đó. Với cách lưu trữ này, việc bổ sung cũng như loại bỏ
một giá trị khỏi tập hợp khóa dễ dàng hơn rất nhiều phương pháp trên.


9

 Cách thứ 3 là nếu chia dãy khóa làm m nhóm, mỗi nhóm được lưu trữ

dưới dạng cây nhị phân tìm kiếm và ghi nhận lại gốc của các cây nhị
phân tìm kiếm đó, phương pháp này có thể nói là tốt hơn hai phương
pháp trên, tuy nhiên dãy khóa phải có quan hệ thứ tự toàn phần thì mới
làm được
1.1.2.2. Tìm kiếm đối kháng
Đây là một loại tìm kiếm đặc biệt, chủ yếu trong các trò chơi đấu trí như
cờ vua, cờ tướng, cờ vây, cờ caro,... Các trò chơi này còn được gọi là 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: tìm đường đi đến các điểm cao nhất giữa hai
đấu thủ. Đặ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 ta hay gọi các trò chơi này là các loại cờ. Đôi khi ta gọi
đây là các trò chơi Minimax (dựa trên tên của thuật toán tìm kiếm cơ bản áp
dụng cho chú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 toán tìm kiếm như thuật toán
minimax, tỉa cây tìm kiếm, và tỉa cây alpha-beta (alpha-beta pruning) [6].


10

Một chiến lược thường được cả người chơi lẫn máy dùng là phân tích
thế cờ chỉ sau một số nước đi nào đó của cả hai bên. Sau khi “nhìn xa” xem

bàn cờ có những khả năng biến đổi như thế nào sau một số nước, ta sẽ đánh
giá độ xấu tốt của các thế cờ nhận được. Tiếp theo, ta sẽ chọn nước đi sẽ dẫn
tới một thế cờ tốt nhất trong số đó có cân nhắc đến cách đi của cả hai bên. Với
máy, thế cờ này được đánh giá là tốt hơn thế cờ kia nhờ so sánh điểm của thế
đó do bộ lượng giá trả lại. Chúng ta chỉ có khả năng xét trước một số hữu hạn
các nước (ví dụ đại kiện tướng chơi cờ vua có thể xét trước 8 - 10 nước đi,
người thường chỉ 2 - 4 nước đi). Rõ ràng là nếu xét càng sâu thì chơi càng
giỏi. Nhưng không thể thực hiện điều này với độ sâu quá lớn được do số nút ở
độ sâu đó có thể trở nên lớn khủng khiếp và không đủ thời gian để phân tích.
Nếu dừng ở một độ sâu hợp lý thì bộ phân tích có thể hoàn thành việc tính
toán trong một thời gian hạn định.
Trong tìm kiếm đối kháng có sử dụng thuật toán Minimax như sau:
 Nếu như đạt đến giới hạn tìm kiếm (đến tầng dưới cùng của cây tìm
kiếm), tính giá trị tĩnh của thế cờ hiện tại ứng với người chơi ở đó. Ghi
nhớ kết quả;
 Nếu như mức đang xét là của người chơi cực tiểu, áp dụng thủ tục
Minimax này cho các con của nó. Ghi nhớ kết quả nhỏ nhất;
 Nếu như mức đang xét là của người chơi cực đại, áp dụng thủ tục
Minimax này cho các con của nó. Ghi nhớ kết quả lớn nhất.
Nguyên tắc Alpha-Beta sử dụng trong tìm kiếm đối kháng: Nếu biết
điều đó thật sự tồi thì đừng mất thời gian tìm hiểu nó sẽ tồi tệ đến đâu. Ý
tưởng này được gọi là nguyên tắc Alpha-Beta do nó được xây dựng trong thủ
tục AlphaBeta. Hai tham số của thủ tục này (theo các đặt tên truyền thống)
được gọi là alpha và beta và dùng để theo dõi các triển vọng - chúng cho biết


11

các giá trị nằm ngoài khoảng [alpha, beta] là các điểm “thật sự tồi” và không
cần phải xem xét nữa. Khoảng [alpha, beta] còn được gọi là cửa sổ alpha,

beta. Trong ngữ cảnh của các trò chơi, nguyên tắc Alpha-Beta nói rằng, mỗi
khi xem xét một nút bất kì, nên kiểm tra các thông tin đã biết về các nút cha,
ông của nó. Rất có thể do có đủ thông tin từ cha, ông nên không cần phải làm
bất cứ việc gì nữa cho nút này. Cũng vậy, nguyên tắc này cũng giúp chỉnh sửa
hoặc xác định chính xác giá trị tại nút cha, ông nó. Như trên nói, một cách để
tiện theo dõi quá trình tính toán là dùng các tham số alpha và beta để ghi lại
các thông tin theo dõi cần thiết. Thủ tục AlphaBeta được bắt đầu tại nút gốc
với giá trị của alpha là   và beta là   . Thủ tục sẽ tự gọi đệ quy chính nó
với khoảng cách giữa các giá trị alpha và beta ngày càng hẹp hơn.
1.1.2.3. Tìm kiếm đường đi
Tìm kiếm đường đi [2] là loại tìm kiếm tối ưu, thông thường với các bài
toán này thì người ta sẽ quy về bài toán tìm đường đi trên đồ thị.
Ví dụ: Hãy tìm đường đi bộ ngắn nhất từ thành phố Thanh Hóa đến thành
phố Thái Nguyên. Lúc này chúng ta coi các địa điểm của thành phố là đỉnh của
đồ thị, còn các cạnh của đồ thị là độ dài đường đi trực tiếp giữa các địa điểm đó.
Nếu giữa hai địa điểm không có đường đi trực tiếp thì trong đồ thị chúng sẽ
không có cạnh nối trực tiếp.
Một số loại tìm kiếm đường đi thông dụng hiện nay:
 Tìm kiếm theo chiều sâu [4]: Trước hết, mọi đỉnh x là đỉnh kề với đỉnh
xuất phát S tất nhiên sẽ đến được từ S. Với mỗi đỉnh x kề với S đó thì tất
nhiên những đỉnh y kề với x cũng đến được từ S ...Điều đó gợi ý cho ta
viết một thủ tục đệ quy DFS (u) mô tả việc duyệt từ đỉnh u bằng cách
thắm đỉnh u và tiếp tục quá trình duyệt DFS (v) với v là một đỉnh chưa
thăm kề với u. Để không một đỉnh nào bị liệt kê tới hai lần, ta sử dụng kỹ


12

thuật đánh dấu, mỗi lần thăm một đỉnh, ta đánh dấu đỉnh đó lại để các
bước duyệt đệ quy kế tiếp không duyệt lại đỉnh đó nữa. Để lưu lại đường

đi từ đỉnh xuất phát
 Tìm kiếm theo chiều rộng [4]: Phương pháp tìm kiếm này còn có một
tên gọi khác là loang. Cơ sở của phương pháp này là “lập lịch” duyệt các
đỉnh. Việc thăm một đỉnh sẽ lên lịch duyệt các đỉnh kề nó sao cho thứ tự
duyệt là ưu tiên chiều rộng (đỉnh nào gần S hơn sẽ được duyệt trước). Giả
sử ta có một danh sách chứa những đỉnh đang chờ thăm. Tại mỗi bước, ta
thăm một đỉnh đầu danh sách và cho những đỉnh chưa “xếp hàng” kề với
nó xếp hàng thêm vào cuối danh sách. Như vậy danh sách chứa những
đỉnh đang chờ sẽ được tổ chức dưới dạng hàng đợi.
 Tìm kiếm theo lựa chọn tốt nhất (best-first search) là một thuật toán
tìm kiếm tối ưu hóa tìm kiếm theo độ sâu bằng cách mở rộng nút hứa
hẹn nhất được chọn theo một quy tắc nào đó [3]. Judea Pearl mô tả tìm
kiếm theo lựa chọn tốt nhất là việc ước lượng mức độ hứa hẹn của nút
n theo một hàm đánh giá heuristic

. Hàm này nói chung có thể phụ

thuộc vào mô tả của n, mô tả về điểm đích, thông tin thu thập được bởi
quá trình tìm kiếm cho tới thời điểm đó, 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. Nhiều tác
giả đã sử dụng nghĩa tổng quát này của thuật ngữ, trong đó có Russell
& Norvig. Các tác giả khác đã sử dụng tìm kiếm theo lựa chọn tốt nhất
để chỉ cụ thể đến quá trình tìm kiếm sử dụng một cách đánh giá
heuristic ước lượng khoảng cách từ điểm cuối của một đường đi tới một
điểm đích, từ đó các đường đi được phán đoán là gần đích hơn sẽ được
mở rộng trước. Russell & Norvig gọi loại tìm kiếm cụ thể này là tìm
kiếm ăn tham theo lựa chọn tốt nhất. Để có được hiệu quả về thời gian


13


chạy cho việc chọn ra ứng cử viên tốt nhất cho việc mở rộng, người ta
thường dùng một hàng đợi ưu tiên để cài đặt cấu trúc dữ liệu lưu trữ
các lựa chọn hiện hành.
1.2. Tổ chức dữ liệu trong tìm kiếm thông tin
1.2.1. Giới thiệu
Cấu trúc dữ liệu [1] là một lĩnh vực nghiên cứu lâu đời của khoa học
máy tính. Hầu hết các chương trình được viết ra, chạy trên máy tính, dù lớn
hay nhỏ, dù đơn giản hay phức tạp, đều phải sử dụng cấu trúc dữ liệu. Có thể
nói rằng không có một chương trình máy tính nào mà không cần và không có
dữ liệu để xử lý. Dữ liệu có thể là dữ liệu đưa vào (input data), dữ liệu trung
gian, dữ liệu đưa ra (output data). Do vậy, việc tổ chức để lưu trữ dữ liệu phục
vụ cho chương trình có ý nghĩa rất quan trọng trong toàn bộ hệ thống chương
trình. Việc tổ chức cấu trúc dữ liệu quyết định rất lớn đến chất lượng của phần
mềm cũng như công sức của người lập trình trong việc thiết kế cài đặt chương
trình. Trong khoa học máy tính, cấu trúc dữ liệu là cách lưu trữ dữ liệu trong
máy tính sao cho nó có thể được sử dụng một cách hiệu quả. Trong thiết kế
nhiều loại chương trình, việc chọn cấu trúc dữ liệu là vấn đề quan trọng. Mỗi
loại cấu trúc dữ liệu phù hợp với một vài loại ứng dụng khác nhau, một số cấu
trúc dữ liệu dành cho những công việc đặc biệt. Sau khi cấu trúc dữ liệu được
chọn, người ta thường dễ dàng nhận thấy thuật toán cần sử dụng. Đôi khi trình
tự công việc diễn ra theo thứ tự ngược lại: cấu trúc dữ liệu được chọn do
những bài toán quan trọng nhất định có thuật toán chạy tốt nhất với một số
cấu trúc dữ liệu cụ thể. Trong cả hai trường hợp, việc lựa chọn cấu trúc dữ
liệu là rất quan trọng. Đúng như Giáo sư Niklaus Wirth, người sáng tác ra
ngôn ngữ Pascal đã có một triết lý: Cấu trúc dữ liệu + Giải thuật = Chương
trình. Như vậy, khi đã có cấu trúc dữ liệu tốt, nắm vững giải thuật thực hiện


14


thì việc thể hiện chương trình bằng một ngôn ngữ cụ thể chỉ là vấn đề thời
gian.
Với các cấu trúc dữ liệu được xây dựng từ các kiểu cơ sở như: kiểu
thực, kiểu nguyên, kiểu ký tự... hoặc từ các cấu trúc đơn giản như mẩu tin, tập
hợp, mảng... lập trình viên có thể giải quyết hầu hết các bài toán đặt ra. Các
đối tượng dữ liệu được xác định thuộc những kiểu dữ liệu này có đặc điểm
chung là không thay đổi được kích thước, cấu trúc trong quá trình sống, do
vậy thường cứng nhắc, gò bó khiến đôi khi khó diễn tả được thực tế vốn sinh
động, phong phú. Các kiểu dữ liệu kể trên được gọi là các kiểu dữ liệu tĩnh.
Một số đối tượng dữ liệu trong chu kỳ sống của nó có thể thay đổi về
cấu trúc, độ lớn, như danh sách các học viên trong một lớp học có thể tăng
thêm, giảm đi... Khi đó nếu cố tình dùng những cấu trúc dữ liệu tĩnh đã biết
như mảng để biểu diễn những đối tượng đó lập trình viên phải sử dụng những
thao tác phức tạp, kém tự nhiên khiến chương trình trở nên khó đọc, do đó
khó bảo trì và nhất là khó có thể sử dụng bộ nhớ một cách có hiệu quả.
Do bản chất của các dữ liệu tĩnh, chúng sẽ chiếm vùng nhớ đã dành cho
chúng suốt quá trình hoạt động của chương trình. Tuy nhiên, trong thực tế, có
thể xảy ra trường hợp một dữ liệu nào đó chỉ tồn tại nhất thời hay không
thường xuyên trong quá trình hoạt động của chương trình. Vì vậy việc dùng
các cấu trúc dữ liệu tĩnh sẽ không cho phép sử dụng hiệu quả bộ nhớ.
Do vậy, nhằm đáp ứng nhu cầu thể hiện sát thực bản chất của dữ liệu
cũng như xây dựng các thao tác hiệu quả trên dữ liệu, cần phải tìm cách tổ
chức kết hợp dữ liệu với những hình thức mới linh động hơn, có thể thay đổi
kích thước, cấu trúc trong suốt thời gian sống. Các hình thức tổ chức dữ liệu
như vậy được gọi là cấu trúc dữ liệu động. Và Stack, Queue, DEQueue,
Heap,... cũng là cấu trúc dữ liệu động.


15


1.2.2. Một số cấu trúc dữ liệu
1.2.2.1. Stack
Stack (ngăn xếp) là một kiểu danh sách được trang bị hai phép toán bổ
sung một phần tử vào cuối danh sách và loại bỏ một phần tử cũng ở cuối danh
sách [4].
Có thể hình dung Stack như hình ảnh một chồng đĩa, đĩa nào được đặt
vào chồng sau cùng sẽ nằm trên tất cả các đĩa khác và sẽ được lấy ra đầu tiên.
Vì nguyên tắc “vào sau ra trước” đó, Stack còn có tên gọi là danh sách LIFO
(Last In First Out) và vị trí cuối danh sách được gọi là đỉnh (Top) của Stack.
Ví dụ về mô hình Stack trong thực tế:

Hình 1.4. Mô hình Stack trong thực tế
1.2.2.2. Queue
Queue (hàng đợi) là một kiểu danh sách được trang bị hai phép toán bổ
sung một phần tử vào cuối danh sách (Rear) và loại bỏ một phần tử ở đầu
danh sách (Front) [4].


16

Có thể hình dung Queue như một đoàn người xếp hàng mua vé: Người
nào xếp hàng trước sẽ được mua vé trước. Vì nguyên tắc “vào trước ra trước”
đó, Queue còn có tên gọi khác là dánh sách kiểu FIFO (First In First Out).
Ví dụ về mô hình Queue trong thực tế:

Hình 1.5. Mô hình Queue trong thực tế
1.2.2.4. Heap
Heap [5] thực chất là một cây cân bằng thỏa mãn các điều kiện sau:
 Một nút có không quá 2 nút con;

 Với Heap Max thì nút gốc là nút lớn nhất, mọi nút con đều không lớn
hơn nút cha của nó. Với Heap Min thì ngược lại.
Với cách định nghĩa trên thì Heap chứa các phần tử có thể giống nhau.
Ngoài ra chúng ta còn có Heap chỉ chứa các phần tử khác nhau.
Ví dụ về Hình 1.6 là Heap Max, trong đó Heap[1] là phần tử có độ ưu
tiên lớn nhất, còn mọi phần tử Heap[i] khác đều có độ ưu tiên bé hơn Heap[i div
2] (Heap[i div 2] là cha của Heap[i])


17

10

8

7

3

8

4

6

1

5

Hình 1.6. Heap Max chứa các phần tử có thể giống nhau

Hình 1.7 là Heap Min, chính vì vậy Heap[1] là phần tử có độ ưu tiên bé
nhất.
5

9

10

13

18

11

19

15
Hình 1.7. Heap Min chứa các phần tử khác nhau

21


18

Chương 2
MỘT SỐ THUẬT TOÁN THAO TÁC TRONG HEAP
2.1. Biểu diễn Heap
Mặc dù được mô tả như cây nhưng Heap có thể được biểu diễn bằng
mảng. Nút con của nút i là 2*i và 2*i+1. Do Heap là cây cân bằng nên độ cao
của 1 nút luôn ≤ logN.

i
A
2*i

2*i+1

B

C

Hình 2.1. Chỉ số con trái và con phải một nút trong Heap
Nếu a[1], a[2], ..., a[n] là một Heap Max thì phần tử a[1] (đầu Heap)
luôn là phần tử lớn nhất trong Heap. Ngược lại nếu là Heap Min thì a[1] là
phần tử nhỏ nhất trong Heap.
Nếu a[left], a[left+1], ..., a[right] là một Heap thì khi cắt bỏ một số
phần tử ở hai đầu của Heap, dãy con còn lại vẫn là một Heap.
Mọi dãy con a[left], a[left+1], ..., a[right] thỏa: 2left > right đều là
Heap
Bảng 2.1. Biểu diễn Heap bằng mảng 1 chiều
i

1

2

3

4

5


6

7

8

9

Heap[i]

10

8

8

7

4

6

1

3

5



×