Tải bản đầy đủ (.docx) (51 trang)

Cài đặt thuật toán tìm kiếm theo chiều sâu, chiều rộng bằng ngôn ngữ Cshaps

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 (991.75 KB, 51 trang )

MỤC LỤC

1


LỜI CẢM ƠN
Để làm được bài báo cáo này, em đã nhận được sự giúp đỡ rất nhiều từ phía Nhà
trường, vì vậy em xin gửi lời cám ơn chân thành đến:
_ Ban Giám Hiệu Trường Đại học Công nghệ Thông tin và Truyền thông Thái Nguyên
đã tạo cho em một môi trường học tập và nghiên cứu đầy đủ về thiết bị, cũng như các cơ
sơ sở vật chất để chúng em có thể yên tâm nghiên cứu; và đã tổ chức cho sinh viên chúng
em có được khoảng thời gian thực tập tìm hiểu về thực tế, để không bỡ ngỡ khi bước vào
môi trường làm việc mới.
_ Khoa Công nghệ Thông tin đã trang bị cho chúng em những kiến thức rất căn bản và
bổ ích về môn học này.
_ GVHD – ThS. Trần Mạnh Tuấn đã nhiệt tình giảng dạy và hướng dẫn em làm tốt bài
báo cáo này.
Thái nguyên, tháng 4/2014
Sinh viên
Lý Thị Việt Chung

2


LỜI NÓI ĐẦU

Trí tuệ nhân tạo (TTNT) là một lĩnh vực của khoa học máy tính, nghiên cứu sự
thiết kế của các tác nhân thông minh. Các áp dụng của TTNT rất đa dạng và phong phú,
hiện nay đã có rất nhiều hệ thông minh ra đời như: các hệ chuyên gia, các hệ điều khiển
tự động, các hệ nhận dạng,…Kỹ thuật của TTNT đã được sử dụng trong việc xây dựng
các hệ mềm nhằm tạo ra các hệ mềm mang yếu tố thông minh, linh hoạt và tiện dụng.


Một trong những nghiên cứu đó là đưa ra các giải thuật tìm kiếm tối ưu nhất phục
vụ việc giải quyết các vấn đề của bài toán một cách nhanh nhất có thể. 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 đó. 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. Tìm kiếm vét cạn (brute-force search)
hay các thuật toán tìm kiếm cơ bản 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 hàm 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. Để hiểu rõ bản chất của thuật giải Heuristic, chúng ta nhất thiết phải nắm vững hai
chiến lược tìm kiếm cơ bản là tìm kiếm theo chiều sâu (Depth First Search) và tìm kiếm
theo chiều rộng (Breath First Search). Cụ thể em sẽ trình bày việc cài đặt thuật toán tìm
kiếm theo chiều sâu và tìm kiếm theo chiều rộng bằng ngôn ngữ C#.
Bố cục bài bái cáo gồm 3 phần:
Chương 1: Cơ sở lý thuyết
Chương 2: Tìm hiểu về ngôn ngữ lập tình
Chương 3: Cài đặt thuật toán
Trong quá trình thực hiện đề tài, tuy có nhiều cố gắng nhưng sẽ không tránh khỏi
những sai sót, rất mong được thầy hướng dẫn và góp ý. Em xin chân thành cảm ơn thầy
Trần Mạnh Tuấn đã tận tình hướng dẫn và tạo điều kiện tốt trong quá trình học tập cũng
như trong quá trình em hoàn thành đề tài này.
3


CHƯƠNG 1: CƠ SỞ LÝ THUYẾT
1.Tổng quan về môn Trí tuệ nhân tạo
1.1.Khái niệm
Trí tuệ nhân tạo trong lĩnh vực công nghệ thông tin (CNTT) là nghành khoa học
nghiên cứu những phương thức để máy tính có khả năng tư duy suy nghĩ như con
người. Ngoài ra trí tuệ nhân tạo còn là ngành nghiên cứu những phương thức để giúp

máy tính làm được những công việc mà tại thời điểm đó nó là những công việc mà
con người chưa làm được hay không làm được. Trí tuệ nhân tạo chia thành hai trường
phái tư duy: TTNT truyền thống và Trí tuệ tính toán.
1.2. Lịch sử phát triển
Vào năm 1943, Warren McCulioch và Walter Pitts bắt đầu thực hiện nghiên cứu ba
cơ sở lý thuyết cơ bản: triết học cơ bản và chức năng của các noron thần kinh; phân
tích các mệnh đề logic; và lý thuyết dự đoán của Turing. Thuật ngữ “Trí tuệ nhân tạo”
(Artificial Intelligence - AI) được thiết lập bởi John McCarthy tại Hội thảo đầu tiên về
chủ đề này vào mùa hè năm 1956.
Vào những năm 1990 và đầu thế kỷ 21, AI đã đạt được những thành tựu to lớn
nhất, AI được áp dụng trong logic, khai phá dữ liệu, chẩn đoán y học và nhiều lĩnh
vực ứng dụng khác trong công nghiệp. Sự thành công dựa vào nhiều yếu tố: tăng khả
năng tính toán của máy tính, tập trung giải quyết các bài toán con cụ thể, xây dựng các
mối quan hệ giữa AI và các lĩnh vực khác giải quyết các bài toán tương tự, và một sự
chuyển giao mới của các nhà nghiên cứu cho các phương pháp toán học vững chắc và
chuẩn khoa học chính xác.
1.3.Các lĩnh vực ứng dụng của AI
- Bài toán lập luận, suy diễn
Khái niệm lập luận (reasoning), và suy diễn (reference) được sử dụng rất phổ biến
trong lĩnh vực AI. Lập luận là suy diễn logic, dùng để chỉ một tiến trình rút ra kết luận
(tri thức mới) từ những giả thiết đã cho (được biểu diễn dưới dạng cơ sở tri thức).
Như vậy, để thực hiện lập luận người ta cần có các phương pháp lưu trữ cơ sở tri
thức và các thủ tục lập luận trên cơ sở tri thức đó.
4


- Biểu diễn tri thức
Muốn máy tính có thể lưu trữ và xử lý tri thức thì cần có các phương pháp biểu
diễn tri thức. Các phương pháp biểu diễn tri thức ở đây bao gồm các ngôn ngữ biểu
diễn và các kỹ thuật xử lý tri thức. Một ngôn ngữ biểu diễn tri thức được đánh giá là

“tốt” nếu nó có tính biểu đạt cao và các tính hiệu quả của thuật toán lập luận trên ngôn
ngữ đó.
Tính biểu đạt của ngôn ngữ thể hiện khả năng biểu diễn một phạm vi rộng lớn các
thông tin trong một miền ứng dụng. Tính hiệu quả của các thuật toán lập luận thể hiện
chi phí về thời gian và không gian dành cho việc lập luận. Tuy nhiên, hai yếu tố này
dường như đối nghịch nhau, tức là nếu ngôn ngữ có tính biểu đạt cao thì thuật toán lập
luận trên đó sẽ có độ phức tạp lớn (tính hiệu quả thấp) và ngược lại (ngôn ngữ đơn
giản, có tính biểu đạt thấp thì thuật toán lập luận trên đó sẽ có hiệu quả cao). Do đó,
một thách thức lớn trong lĩnh vực AI là xây dựng các ngôn ngữ biểu diễn tri thức mà
có thể cân bằng hai yếu tố này, tức là ngôn ngữ có tính biểu đạt đủ tốt (tùy theo từng
ứng dụng) và có thể lập luận hiệu quả.
- Lập kế hoạch: khả năng suy ra các mục đích cần đạt được đối với các nhiệm vụ
đưa ra, và xác định dãy các hành động cần thực hiện để đạt được mục đích đó.
- Học máy: là một lĩnh vực nghiên cứu của AI đang được phát triển mạnh mẽ và có
nhiều ứng dụng trong các lĩnh vực khác nhau như khai phá dữ liệu, khám phá tri thức,

- Xử lý ngôn ngữ tự nhiên: là một nhánh của AI, tập trung vào các ứng dụng trên
ngôn ngữ của con người. Các ứng dụng trong nhận dạng tiếng nói, nhận dạng chữ viết,
dịch tự động, tìm kiếm thông tin,…
- Hệ chuyên gia: cung cấp các hệ thống có khả năng suy luận để đưa ra những kết
luận. Các hệ chuyên gia có khả năng xử lý lượng thông tin lớn và cung cấp các kết
luận dựa trên những thông tin đó. Có rất nhiều hệ chuyên gia nổi tiếng như các hệ
chuyên gia y học MYCIN, đoán nhận cấu trúc phân tử từ công thức hóa học
DENDRAL, …
- Robotics
1.4.Giải quyết vấn đề bằng tìm kiếm
5


Vấn đề tìm kiếm một cách tổng quan có thể hiểu là tìm một đối tượng thỏa mãn

một số đòi hỏi nào đó, trong một tập hợp rộng lớn các đối tượng chúng ta có thể kể ra
rất nhiều vấn đề mà việc giải quyết nó được quy về vấn đề tìm kiếm.
Các trò chơi chẳng hạn cờ vua, cờ caro có thể xem như một vấn đề tìm kiếm.
Trong số rất nhiều nước đi được phép thực hiện ra phải tìm ra rất nhiều nước đi dẫn
đến tình thế kết cuộc mà ta là người thắng.
Chứng minh định lý cũng có thể xem như vấn đề tìm kiếm. Cho một tập các tiên đề
và các luật suy diễn trong trường hợp này mục tiêu của ta là tìm ra một luật chứng
minh (một dãy các luật suy diễn được áp dụng) để được đưa đến công thức mà ta cần
chứng minh.
Trong các lĩnh vực nghiên cứu của TTNT chúng ta thường xuyên phải đối đầu với
vấn đề tìm kiếm. Đặc biệt trong lập kế hoạch và học máy tìm kiếm có vai trò quan
trong.
Trong phần này chúng ta sẽ nghiên cứu các ký thuật tìm kiếm cơ bản được áp
dụng để giải quyết các vấn đề và được áp dụng rộng rãi trong các lĩnh vực khác của
TTNT. Cụ thể là nghiên cứu các chiến lược tìm kiếm mù, đi sâu vào chiến lược tìm
kiếm theo bề rộng (breadth-first search) và tìm kiếm theo độ sâu (depth-first search)
Trong tìm kiếm theo bề rộng, tại mỗi bước ta sẽ chọn trạng thái để phát triển là
trạng thái được sinh ra trước các trạng thái chờ phát triển khác. Còn trong tìm kiếm
theo độ sâu, trạng thái được chọn để phát triển là trạng thái được sinh ra sau cùng
trong số các trạng thái chờ phát triển.
Chúng ta sử dụng danh sách L để lưu các trạng thái đã được sinh ra và chờ được
phát triển. Mục tiêu của tìm kiếm trong không gian trạng thái là tìm đường đi từ trạng
thái ban đầu tới trạng thái đích, do đó ta cần lưu lại vết của đường đi. Ta có thể sử
dụng hàm father để lưu lại cha của mỗi đỉnh trên đường đi, father(v) = u nếu cha của
đỉnh v là u.
1.5.Phân tích bài toán
1.5.1. Mục đích bài toán

6



a. Tìm kiếm theo chiều sâu
Tìm kiếm theo chiều sâu là thuật toán duyệt hoặc tìm kiếm trên một cây hoặc một
đồ thị. Thuật toán khởi đầu tại gốc (hoặc chọn một đỉnh nào đó coi như gốc) và phát triển
xa nhất có thể theo mỗi nhánh. Thuật toán tìm kiếm theo chiều sâu ứng dụng cho nhiều
giải thuật như: xác định các thành phần liên thông của đồ thị; kiểm tra một đồ thị có là đồ
thị phẳng hay không,…
b. Tìm kiếm theo chiều rộng
Tìm kiếm theo chiều rộng là thuật toán tìm kiếm trên tất cả các nút của một mức
trong không gian bài toán trước khi chuyển sang các nút của mức tiếp theo. Tìm kiếm
theo chiều rộng chủ yếu được sử dụng để tìm đường đi ngắn nhất theo số cạnh giữa hai
đỉnh của một đồ thị, tìm tất cả các đỉnh trong một thành phần liên thông,...
1.5.2. Cách thực hiện
a. Tìm kiếm theo chiều sâu
 Sơ lược thuật toán tìm kiếm chiều sâu:

Trong tìm kiếm theo chiều sâu, tại trạng thái (đỉnh hoặc nút) hiện hành, ta chọn
một trạng thái kế tiếp (trong tập các trạng thái có thể biến đổi thành từ trạng thái hiện tại)
làm trạng thái hiện hành cho đến lúc trạng thái hiện hành là trạng thái đích. Trong trường
hợp tại trạng thái hiện hành, ta không thể biến đổi thành trạng thái kế tiếp thì ta sẽ quay
lui (Back-tracking) lại trạng thái trước trạng thái hiện hành (trạng thái biến đổi thành
trạng thái hiện hành) để chọn đường khác. Nếu ở trạng thái trước này mà cũng không thể
biến đổi được nữa thì ta quay lui lại trạng thái trước nữa và cứ thế. Nếu đã quay lui đến
trạng thái khởi đầu mà vẫn thất bại thì kết luận là không có lời giải. Hình ảnh sau minh
họa hoạt động của tìm kiếm theo chiều sâu.

7


Hình 1.1: Hình ảnh của tìm kiếm chiều sâu.

Nó chỉ lưu ý "mở rộng" trạng thái được chọn mà không "mở rộng" các trạng thái
khác.
 Kỹ thuật tìm kiếm chiều sâu:

Tư tưởng chính của thuật toán là: Giả sử chúng ta đang xét trên đồ thị G. Từ một
đỉnh u 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 u 0, chúng ta sẽ có hai khả năng sẽ
xảy ra:
- Nếu như tồn tại một đỉnh v 0 kề với u0 mà chưa được thăm thì đỉnh v 0 đó 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 u 0 đề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.
Cụ thể là tìm kiếm theo chiều sâu trong không gian bài toán được bắt đầu từ một
nút rồi tiếp tục cho đến khi hoặc đến ngõ cụt hoặc đến đích. Tại mỗi nút có luật trong tài,
chẳng hạn, “đi theo nút cực trái”, hướng dẫn việc tìm. Nếu không đi tiếp được, gọi là đến
ngõ cụt, hệ thống quay lại một mức trên đồ thị và tìm theo hướng khác, chẳng hạn, đến
nút “sát nút cực trái”. Thuật toán tìm kiếm theo chiều sâu được hình dung như việc khảo

8


sát một cây bắt đầu từ gốc đi theo mọi cành có thể được, khi gặp cành cụt thì quay lại xét
cành chưa đi qua.
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).
b. Tìm kiếm theo chiều rộng
 Sơ lược thuật toán tìm kiếm chiều rộng:

Ngược lại với tìm kiếm theo kiểu chiều sâu, tìm kiếm chiều rộng mang hình ảnh

của vết dầu loang. Từ trạng thái ban đầu, ta xây dựng tập hợp S bao gồm các trạng thái kế
tiếp (mà từ trạng thái ban đầu có thể biến đổi thành). Sau đó, ứng với mỗi trạng thái Tk
trong tập S, ta xây dựng tập Sk bao gồm các trạng thái kế tiếp của Tk rồi lần lượt bổ sung
các Sk vào S. Quá trình này cứ lặp lại cho đến lúc S có chứa trạng thái kết thúc hoặc S
không thay đổi sau khi đã bổ sung tất cả Sk.

Hình 1.2 : Hình ảnh của tìm kiếm chiều rộng.
Tại một bước, mọi trạng thái đều được mở rộng, không bỏ sót trạng thái nào.
 Kỹ thuật tìm kiếm chiều rộng:

9


Kỹ thuật tìm kiếm rộng là tìm kiếm trên tất cả các nút của một mức trong không
gian bài toán trước khi chuyển sang các nút của mức tiếp theo. Kỹ thuật tìm kiếm rộng bắt
đầu từ mức thứ nhất của không gian bài toán, theo hướng dẫn của luật trọng tài, chẳng
hạn “đi từ trái sang phải”. Nếu không thấy lời giải tại mức này, nó chuyển xuống mức sau
để tiếp tục … đến khi định vị được lời giải nếu có.
Thuật toán tìm kiếm theo chiều rộng 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 ngăn xếp (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).
1.6. Cấu trúc dữ liệu và cách biểu diễn các trạng thái của bài toán

Hình 1.3:Bài toán tím kiếm
1.6.1. Tìm kiếm theo chiều sâu
Với dữ liệu cho như hình 3, thuật toán tìm kiếm theo chiều sâu bắt đầu thăm đỉnh A,
đi theo cạnh trái, tiếp tục tìm kiếm xong ở cây con trái mới chuyển sang tìm kiếm ở cây
con phải. Thứ tự duyệt các đỉnh là: A, B, D, F, C, G, E.

Quá trình duyệt các đỉnh diễn ra như sau: Sau khi thăm đỉnh A, vì B chưa được thăm
nên theo cạnh AB ta thăm B, tiếp tục theo cạnh BD tới viếng thăm D. Từ D không thể
tiếp tục đi xa hơn, ta quay lại B. Từ B, theo BF đến thăm F, từ F không thể đi xa hơn
được nữa nên ta quay lại B. Tại B, vì tất cả các khả năng từ B đã xem xét nên ta quay lại
10


A. Từ A, ta theo cạnh AC tới thăm C, tiếp tục theo cạnh CG tới thăm G. Từ G không thể
đi xa hơn được nữa nên ta quay lại C. Tại C, tất cả các khả năng từ C đã xét nên ta lại
quay về A và theo cạnh AE tới thăm đỉnh E. Như vậy tất cả các đỉnh của đồ thị đều được
duyệt đến.
1.6.2. Tìm kiếm theo chiều rộng
Cũng với dữ liệu như hình 3, thuật toán tìm kiếm theo chiều rộng bắt đầu thăm đỉnh
A, đi theo lần lượt các đỉnh con, rồi lần lượt tìm kiếm các đỉnh con phía dưới. Thứ tự
duyệt các đỉnh là: A, B, C, E, D, F, G.
Quá trình duyệt các đỉnh diễn ra như sau: Sau khi thăm đỉnh A, ta lần lượt thăm hết
các đỉnh con của A là B, C, E theo các cạnh tương ứng. Sau khi duyệt xong các đỉnh con
của A, ta lần lượt duyệt các đỉnh con của B là D, F và lần lượt duyệt các đỉnh con của C là
G. Vì E không có đỉnh con nên quay về duyệt các đỉnh con của các đỉnh B, C. Các đỉnh
D, F, G đều không có đỉnh con nên thuật toán kết thúc, tất cả các đỉnh của đồ thị đều đã
được duyệt đến.
1.6.3. Một số bài toán liên quan
a) Trạng thái xa nhất
Trò chơi 8-puzzle gồm một khay hình vuông với 8 mảnh vuông được đặt lên 8 ô
vuông. Ô vuông còn lại rỗng. Mỗi mảnh có ghi một con số. Một mảnh kề với ô rỗng có
thể được đẩy sang ô rỗng này. Một ván chơi bao gồm trạng thái bắt đầu và trạng thái kết
thúc. Người chơi phải biến đổi đến trạng thái kết thúc bằng cách di chuyển các mảnh
vuông. Bài toán 8-puzzle yêu cầu phải biến đổi với số bước ít nhất.

11



Hình 1.4: Trò chơi 8-puzzle
Nhưng trong bài toán này (bài toán trạng thái xa nhất), bạn được cho một trạng thái
bắt đầu. Hãy tìm trạng thái xa nhất (theo nghĩa số bước đi) trong tất cả các trạng thái đến
được.
Hướng dẫn: Đây cũng là một bài toán loang. Nhưng hơi khó khăn ở chỗ lưu vết, vì
có đến 9!=362880 trạng thái => không đủ bộ nhớ. Có thể khắc phục bằng cách dùng kỹ
thuật băm. Cách làm như sau: cho tương ứng (1-1) giữa mỗi trạng thái với một số nguyên
trong khoảng 1->362880, sau đó dùng một bảng băm với kích thước sao cho đủ bộ nhớ.
Tiếp đó ánh xạ mỗi trạng thái vào một khe trong bảng băm (có thể dùng phép đồng dư) để
lưu.
b) Mã trên bàn cờ 5x5
Có các quân mã trắng và đen trên một bàn cờ 5x5. Có 12 quân mỗi loại và chỉ có
một ô rỗng. Tại mỗi thời điểm, một quân mã có thể di chuyển đến một ô rỗng (cách đi của
quân mã như luật cờ vua thông thường).
12


Cho một trạng thái ban đầu của bàn cờ, hãy xác định số bước đi ít nhất để đạt được
trạng thái sau:

Hình 1.5:Bàn cờ 5x5
1.7.Mã giả các thuật toán được sử dụng
1.7.1. Tìm kiếm theo chiều sâu
a) Giải thuật: Sử dụng danh sách Open kiểu LIFO, Close kiểu FIFO.
Thuật toán tìm kiếm theo chiều sâu được mô tả bởi thủ tục sau:
Procedure Depth _First_Search;
Begin
1. Khởi tạo danh sách L chỉ chứa trạng thái ban đầu;

2. loop do
2.1 if L rỗng then

{ Thông báo tìm kiếm thất bại;stop};
2.2 Loại trạng thái u ở đầu danh sách L;
2.3 If u là trạng thái kết thúc then

{ Thông báo tìm kiếm thành công;stop};
2.4 For mỗi trạng thái v kề u do{
Đặt v vào cuối danh sách L;
Father (v)  u}
End;

13


b) Ví dụ:
Cho cây như hình sau: Đỉnh A và Đích J

Các bước chi tiết thực hiện giải thuật:
X

Open

Close

[A]

[]


A

[ B,C,D ]

[A]

B

[ E,F,C,D ]

[ A,B ]

E

[ F,C,D ]

[ A,B,E ]

F

[ C,D ]

[ A,B,E,F ]

C

[ G,D ]

[ A,B,E,F,C ]
14



G

[ J,D ]

[ A,B,E,F,C,G ]

J

[D]

[ A,B,E,F,C,G ]

Ta có J ∈ Đích ⇒ Thành Công. Xây dựng đường đi. A → C → G → J.
Kết quả đường đi trên cây là:

c. Ưu và nhược điểm:
 Ưu điểm:

 Nếu bài toán có lời giải, phương pháp tìm kiếm sâu bảo đảm tìm ra lời giải.
 Kỹ thuật tìm kiếm sâu tập trung vào đích, con người cảm thấy hài lòng khi các
câu hỏi tập trung vào vấn đề chính.
 Do cách tìm của kỹ thuật này, nếu lời giải ở rất sâu, kỹ thuật tìm sâu sẽ tiết kiệm
thời gian.
 Nhược điểm:
15


 Tìm sâu khai thác không gian bài toán để tìm lời giải theo thuật toán đơn giản

một cách cứng nhắc. Trong quá trình tìm nó không có thông tin nào hỗ trợ để
phát hiện lời giải. Nếu chọn nút ban đầu không thích hợp có thể không dẫn đến
đích của bài toán.
 Không phù hợp với không gian bài toán lớn, kỹ thuật tìm kiếm sâu có thể không
đến lời giải trong khoảng thời gian vừa phải.
1.7.2. Tìm kiếm theo chiều rộng
a. Giải thuật: Sử dụng danh sách Open và Close kiểu FIFO.
Procedure Breadth_First_Search;
begin
1. Khởi tạo danh sách L chỉ chứa trạng thái ban đầu;
2. loop do
2.1 If L rỗng then
{thông báo tìm kiếm thất bại; stop};
2.2 Loại trạng thái u ở đầu danh sách L;
2.3. If u là trạng thái kết thúc then;
{ thông báo tìm kiếm thành công ;stop};
2.4. For mỗi trạng thái v kề u do {
Đặt v vào cuối danh sách L;
father(v) ←u}
end;
b) Ví dụ:
Cho cây như hình sau: Đỉnh A và Đích K

16


Các bước chi tiết thực hiện giải thuật:

X


Open
[A]

Close
[]

A
B
C

[ B,C,D ]
[ C,D,E,F ]
[ D,E,F,G ]

[A]
[ A,B ]
[ A,B,C ]
17


D
E
F
G
H
I
J
K

[ E,F,G,H,I ]

[ F,G,H,I,J,K ]
[ G,H,I,J,K ]
[ H,I,J,K,L ]
[ I,J,K,L ]
[ J,K,L ]
[ K,L ]

[ A,B,C,D ]
[ A,B,C,D,E ]
[ A,B,C,D,E,F ]
[ A,B,C,D,E,F,G ]
[ A,B,C,D,E,F,G,H ]
[ A,B,C,D,E,F,G,H,I ]
[ A,B,C,D,E,F,G,H,I,J ]

Ta có K ∈ Đích ⇒ Thành công. Xây dựng đường đi: A → B → E → K
Kết quả đường đi trên cây:

c) Ưu và nhược điểm:
 Ưu điểm:

 Kỹ thuật tìm kiếm rộng là kỹ thuật vét cạn không gian trạng thái bài toán vì vậy
sẽ tìm được lời giải nếu có.
 Đường đi tìm được đi qua ít đỉnh nhất.
 Nhược điểm:

18


Tìm kiếm lời giải theo thuật toán đã định trước, do vậy tìm kiếm một cách máy

móc; khi không có thông tin hỗ trợ cho quá trình tìm kiếm, không nhận ra ngay
lời giải.
 Không phù hợp với không gian bài toán kích thước lớn. Đối với loại bài toán

này, phương pháp tìm rộng đối mặt với các nhu cầu:
o Cần nhiều bộ nhớ theo số nút cần lưu trữ.
o Cần nhiều công sức xử lý các nút, nhất là khi các nhánh cây dài, số nút tăng.
o Dễ thực hiện các thao tác không thích hợp, thừa, đưa đến việc tăng đáng kể
số nút phải xử lý.
 Không hiệu quả nếu lời giải ở sâu. Phương pháp này không phù hợp cho trường
hợp có nhiều đường dẫn đến kết quả nhưng đều sâu.
 Giao tiếp với người dùng không thân thiện. Do duyệt qua tất cả các nút, việc tìm
kiếm không tập trung vào một chủ đề.
1.8. So sánh thuật toán tìm kiếm theo chiều sâu và theo chiều rộng

Tính hiệu quả

Chiều sâu
Chiều rộng
Hiệu quả khi lời giải nằm sâu Hiệu quả khi lời giải nằm
trong cây tìm kiếm và có một gần gốc của cây tìm kiếm.
phương án chọn hướng đi Hiệu quả của chiến lược
chính xác. Hiệu quả của chiến phụ thuộc vào độ sâu của
lược phụ thuộc vào phương án lời giải. Lời giải càng xa
chọn hướng đi. Phương án gốc thì hiệu quả của chiến
càng kém hiệu quả thì hiệu quả lược càng giảm. Thuận lợi
của chiến lược càng giảm. khi muốn tìm nhiều lời giải.
Thuận lợi khi muốn tìm chỉ

một lời giải.

Lượng bộ nhớ sử Chỉ lưu lại các trạng thái chưa Phải lưu toàn bộ các trạng
dụng để lưu trữ xét đến.

thái.

các trạng thái
Trường hợp xấu Vét cạn toàn bộ

Vét cạn toàn bộ
19


nhất
Trường
nhất

hợp

tốt Phương án chọn hướng đi tuyệt

Vét cạn toàn bộ

đối chính xác. Lời giải được
xác định một cách trực tiếp.

Tìm kiếm chiều sâu và tìm kiếm chiều rộng đều là các phương pháp tìm kiếm có
hệ thống và chắc chắn tìm ra lời giải. Tuy nhiên, do bản chất là vét cạn nên với những bài
toán có không gian lớn thì ta không thể dùng hai chiến lược này được. Hơn nữa, hai chiến
lược này đều có tính chất "mù quáng" vì chúng không chú ý đến những thông tin (tri
thức) ở trạng thái hiện thời và thông tin về đích cần đạt tới cùng mối quan hệ giữa chúng.


20


CHƯƠNG 2:GIỚI THIỆU VỀ NGÔN NGỮ LẬP TRÌNH C#
2.1. Lịch sử ngôn ngữ C#
Ngôn ngữ C# được phát triển bởi đội ngũ kỹ sư của Microsoft, trong đó người dẫn
đầu là Anders Hejlsberg và Scott Wiltamuth. Cả hai người này điều là những người nổi
tiếng, trong đó Anders Hejlsberg được biết đến là tác giả của Turbo Pascal,
một ngôn ngữ lập trình PC phổ biến. Và ông đứng đầu nhóm thiết kế Borland
Delphi, một trong những thành công đầu tiên của việc xây dựng môi trường phát triển
tích hợp (IDE) cho lập trình client/server.
2.2. Giới thiệu ngôn ngữ lập trình C#.net
Ngôn ngữ C# khá đơn giản, chỉ khoảng 80 từ khóa và hơn mười mấy kiểu dữ liệu
được xây dựng sẵn. Tuy nhiên, ngôn ngữ C# có ý nghĩa cao khi nó thực thi những khái
niệm lập trình hiện đại. C# bao gồm tất cả những hỗ trợ cho cấu trúc, thành phần
component, lập trình hướng đối tượng. Những tính chất đó hiện diện trong một ngôn
ngữ lập trình hiện đại. Và ngôn ngữ C# hội đủ những điều kiện như vậy, hơn nữa
nó được xây dựng trên nền tảng của hai ngôn ngữ mạnh nhất là C++và Java.
C# được xây dựng và kiến trúc bởi Anders Hejlsberg, người đã viết nên trình biên
dịch Pascal và có nhiều đóng góp cho Delphi cũng như Java.
C# là một trong rất nhiều ngôn ngữ lập trình được hỗ trợ bởi .NET Framework .
C# do Microsoft đề ra là ngôn ngữ hướng đối tượng rất thuần nhất và trong sáng, nó
hiện thực hầu hết các tính chất tốt của mô hình hướng đối tượng giống như Java.
C# sẽ được dịch ra mã máy để chạy trên nền .Net, nền này cung cấp rất nhiều đối
tượng mạnh, phong phú và đa dạng để giải quyết nhiều vấn đề phổ biến trong lập
trình.
Ngôn ngữ C# chứa các từ khóa cho việc khai báo những kiểu lớp đối tượng mới và
những phương thức hay thuộc tính của lớp và cho việc thực thi đóng gói, kế thừa, và
đa hình đây là ba thuộc tính cơ bản của bất cứ ngôn ngữ lập trình hướng đối tượng.

C# hỗ trợ giao diện (interface), nó được xem như một cam kết với một lớp cho
những dịch vụ mà giao diện quy định. Trong ngôn ngữ C#, một lớp chỉ có thể kế thừa
21


từ duy nhất một lớp cha, tức là không cho đa kế thừa như trong ngôn ngữ C++, tuy
nhiên một lớp có thể thực thi nhiều giao diện.
Ngôn ngữ C# cung cấp những đặc tính hướng thành phần (component-oriented),
như là những thuộc tính, những sự kiện. Lập trình hướng thành phần được hỗ trợ bởi
CLR cho phép lưu trữ siêu dữ liệu (metadata) với mã nguồn cho một lớp. Metadata
mô tả cho một lớp, bao gồm những phương thức và những thuộc tính của nó, cũng
như những sự bảo mật cần thiết và những thuộc tính khác. Mã nguồn chứa đựng
những logic cần thiết để thực hiện những chức năng của nó.
Ngôn ngữ C# là ngôn ngữ hỗ trợ việc truy cập bộ nhớ trực tiếp sử dụng kiểu con
trỏ của C++ và từ khóa cho dấu ngoặc [] trong toán tử.
C# là ngôn ngữ đơn giản
C# là ngôn ngữ hiện đại
C# là ngôn ngữ hướng đối tượng
C# là ngôn ngữ mạnh mẽ và mềm dẻo
C# là ngôn ngữ có ít từ khóa
C# là ngôn ngữ hướng module
C# sẽ trở nên phổ biến
Có 2 kiểu ứng dụng chính trong C#.net: Console application, Window application
-

Console application được thiết kế để chạy các dòng lệnh không hỗ trợ giao diện

-

cho người sử dụng.

Window application được thiết kế để chạy trên màn hình nền có hỗ trợ giao diện
cho người sử dụng.
Nền tảng về ngôn ngữ C#

2.3. Lớp, đối tượng và kiểu
Bản chất của lập trình hướng đối tượng là tạo ra các kiểu mới. Một kiểu biểu diễn
một vật gì đó. Giống với các ngôn ngữ lập trình hướng đối tượng khác, một kiểu trong C#
cũng định nghĩa bằng từ khoá class(và được gọi là lớp) còn thểhiện của lớp được gọi là
đối tượng.
Xem Ví dụ1 ta thấy cách khai báo một lớp HelloWorld. Ta thấy ngay là cách khai báo và
nội dung của một lớp hoàn toàn giống với ngôn ngữ Java và C++, chỉ có khác là cuối khai
báo lớp không cần dấu “;”
22


2.3.1. Phương thức (Main)
Các hành vi của một lớp được gọi là các phương thức thành viên (gọi tắt là phương
thức) của lớp đó. Một phương thứclà một hàm(phương thức thành viên còn gọi là hàm
thành viên). Các phương thức định nghĩa những gì mà một lớp có thể làm. Cách khai báo,
nội dung và cách sửdụng các phương thức giống hoàn toàn với Java và C++. Trong ví
dụtrên có một phương thức đặc biệt là phương thức Main()(như hàm main()trong C++) là
phương thức bắt đầu của một ứng dụng C#, có thể trảvề kiểu voidhay int. Mỗi một
chương trình (assembly) có thể có nhiều phương thức Main nhưng khi đó phải chỉ định
phương thức Main() nào sẽ bắt đầu chương trình.
b) Namespace
- .NET cung cấp một thư viện các class rất đồ sộ, trong đó Console là một class nhỏ trong
thư viện các class này.
- Mỗi class có một tên riêng, vì vậy người lập trình không thể nào nhớ hết tên các class
trong .NET. Để giải quyết vấn đề này là việc tạo ra một namespace, namespace sẽ hạn chế
phạm vi của một tên, làm cho tên này chỉ có ý nghĩa trong vùng đã định nghĩa.

2.4. Định danh – biến và toán tử trong C#
2.4.1. Định danh
Định danh là tên mà người lập trình chỉ định cho các kiểu dữ liệu, các phương thức,
biến, hằng, hay đối tượng....
Một định danh phải bắt đầu với một ký tự chữ cái hay dấu gạch dưới, các ký tự còn lại
phải là ký tự chữ cái, chữ số, dấu gạch dưới.
Theo qui ước đặt tên của Microsoft thì đề nghị sử dụng cú pháp lạc đà (camel
notation) bắt đầu bằng ký tự thường để đặt tên cho các biến, với ký tự đầu tiên là hoa cho
cách đặt tên hàm và hầu hết các định danh còn lại
Các định danh không được trùng với các từ khoá trong C#

23


2.4.2. Biến
- Dùng để lưu trữ giá trị mang một kiểu dữ liệu nào đó.
Khai báo biến: Sau khi khai báo biến phải gán giá trị cho biến
<Kiểu_Dữ_Liệu> <tên_biến> [ = <giá_trị> ] ;
Phạm vi hoạt động của biến là vùng đoạn mã mà từ đấy biến có thể được truy xuất.Trong
một phạm vi hoạt động (scope), không thể có hai biến cùng mang một tên trùng nhau.
2.4.3. Hằng
Một hằng (constant) là một biến nhưng trị không thể thay đổi được suốt thời gian
thi hành chương trình. Đôi lúc ta cũng cần có những giá trị bao giờ cũng bất biến.
- Hằng được phân làm 3 loại:
+ Giá trị hằng (literal)
+ Biểu tượng hằng (symbolic constants)
+ Kiểu liệt kê (enumerations)
2.4.4. Toán tử
24



a) Toán tử toán học: + , - , * , / , %
b) Toán tử tăng / giảm: += , -= , *= , /= , %=
c) Toán tử tăng / giảm 1 đơn vị: ++ , --d) Toán tử gán: =
e) Toán tử quan hệ: == , != , > , >= , < , <=
f) Toán tử logic: ! , && , ||
g) Toán tử 3 ngôi: (Điều_Kiện) ? (Biểu_Thức_1) : (Biểu_Thức_2) ;
2.5. Kiểu dữ liệu – Cấu trúc điều kiện – Cấu trúc lặp
2.5.1. Kiểu dữ liệu và xây dựng sẵn
Ngôn ngữ C# đưa ra các kiểu dữ liệu xây dựng sẵn rất hữu dụng, phù hợp với một
ngôn ngữ lập trình hiện đại, mỗi kiểu dữ liệu được ánh xạ đến một kiểu dữ liệu được hỗ
trợ bởi hệ thống xác nhận ngôn ngữ chung (Common Language Specification: CLS) trong
MS.NET. Việc ánh xạ các kiểu dữ liệu nguyên thuỷ của C# đến các kiểu dữ liệu của .NET
sẽ đảm bảo các đối tượng được tạo ra trong C# có thể được sử dụng đồng thời với các đối
tượng được tạo bởi bất cứ ngôn ngữ khác được biên dịch bởi .NET, như VB.NET.
Bảng sau sẽ mô tả một số các kiểu dữ liệu được xây dựng sẵn
C# hỗ trợ 8 kiểu dữ liệu số nguyên sau:

Name

CTS Type

Sbyte

System.SByte

Short

Int


System.Int16

System.Int32

Description
8-bit

signed

integer
16-bit

signed

integer
32-bit

Range (min:max)

-128:127 (-27:27-1)

-32,768:32,767 (-215:215-1)

signed -2,147,483,648:2,147,483,647

25

(-



×