Luận văn mô phỏng một số thuật toán trên đồ thị
Trang 1DAI HOC QUOC GIA HÀ NỘI TRUONG DAI HOC CONG NGHE
NGUYEN TH] CHINH
MO PHONG MOT SO THUAT TOAN TREN DO THI
LUAN VAN THAC SI
Hà Nội - 2011
Trang 2DAI HOC QUOC GIA HÀ NỘI TRUONG DAI HOC CONG NGHE
NGUYEN THI CHINH
MO PHONG MOT SO THUAT TOAN TREN DO THI
Ngành: Công nghệ thông tin
Chuyên ngành: Hệ thông thông tin
Trang 3LOI CAM DOAN
Tôi xin cam đoan, kết quả luận văn hoàn toàn là kết quả của tự bản thân
tôi tìm hiểu, nghiên cứu dưới sự hướng dẫn của TS Hồ Cẩm Hà
Các tài liệu tham khảo được trích dẫn và chú thích đầy đủ
Học viên
Nguyễn Thị Chinh
Trang 4LOI CAM ON Trước hết, tôi muốn gửi lời cảm đến các Thầy, Cô trong khoa Công nghệ
thông tin- Trưởng Đại học Công nghệ - Đại học Quốc gia Hà nội đã truyền đạt các kiến thức quý báu cho tôi trong suốt thời gian học tập tại trưởng Đặc biệt,
tôi xin gửi lời cảm ơn sâu sắc tới cô giáo hướng dân 1S Hỗ Cảm Hà, người đã tận tình chỉ bảo và hướng dân vé mặt chuyên môn cho tôi trong suốt quả trình
thực hiện luận văn nảy
Cũng qua đây, tôi xin gửi lời cảm ơn đến Ban Giám hiệu trường THPT
Chuyên Đại học Sự phạm Hà Nội, nơi tôi đang công tác đã tạo mọi điễu kiện thuận lợi cho tôi trong thời gian học tập cũng nhự trong suốt quá trình thực hiện luận văn tốt nghiệp
Cuối cùng, tôi xin cảm ơn gia đình, bạn bè, đồng nghiệp đã luôn ủng hộ, động viên tôi rất nhiễu để tôi yên tâm nghiên cứu và hoàn thành luận văn Trong suốt quá trình làm luận văn, bản thân tôi đã cô gắng tập trung tìm hiểu, nghiên cứu và tham khảo thêm nhiễu tài liệu liên quan Tuy nhiên, do thời gian hạn chế
và bản thân còn chưa có nhiều kinh nghiệm trong nghiên cứu khoa học, chắc
chan ban luận văn vẫn còn nhiễu thiếu sót Tôi rất mong được nhận sự chỉ bảo
của các Thầy Cô giáo và các góp ý của bạn bè, đông nghiệp để luận văn được
hoàn thiện hơn
Hà Nội, ngày l2 thang 06 nam 2011
Nguyễn Thị Chỉnh
Trang 5MUC LUC
LOT CAM ON cccccscssessessessessessesseseesseseesceneanecucancanesecsseseaucaueseeseeseeseeaseneansenen 6 LỜI NÓI ĐẦU . ¿52t 2 2222221 22122127127117121TE1717111717111111.111 me 10 Chương l1 MỘT SỐ KIÊN THỨC CƠ BẢN VẼ THUẬT TOÁN 12
1 Khái niệm bài toán Tìn học 39399290 ng ng 9 kg 12
2 Khái niệm thuật toán - c Ăn ng nh ren 12
3 Các tính chất của thuật toán . -:- + 2t22t22xt+rerertrrrrrrrrrrrrrrrree 13
4 Độ phức tạp và xác định độ phức tạp của thuật toán - ‹- 14
5 Chi phí thực hiện thuật toán - - c S22 2S S1 n9 11 v33 ra 18
6 Ba bài toán trên mô hình đồ thị được đưa vào giảng dạy trong trường Trung học Phô thông Chuyên t1 E111 8 1 5111111111 11g ru 18
6.1 Một số khái niém co ban VE 46 thi eecseessesseeseeceeseeseeseesteeseeeneeneen 18
6.1.1 Khái niệm đồ thị (Graph) - - - xxx gkekekeerkseekeed 18
6.1.2 Cac khai ni€m CO DAN 00 eee eeceseeesececeeeceeeseccensecseseesseeeeeceneesss 19 6.2 Bài toán tim kiém trén 46 thi eeseeseecessessesseeteeeeseeseeseeeeeteeeeneenee 21 6.2.1 Phát bi€u bai tA oo eseececseeeseeseeseeseeeneeseceneenecsnecneeneeeneeeesetenes 21 6.2.2 Giới thiệu thuật toán tìm kiếm DES và BFS 22 6.2.3 Độ phức tạp tính toán của thuật toán DFS và BES 24
6.3 Bài toán tìm đường đi ngắn nhất trên đồ thị có trọng sỐ 24
6.3.1 Phát biểu bài toán ¿5c 24 6.3.2 Giới thiệu thuật toán Ford - Bellman - - << << << << 25 6.2.3 Giới thiệu thuật toán thuật toán DIjkstra - - 26
6.3.4 DO (is ii nnnHi(Á( 28 6.4 Các thuật toán tìm kiếm trên cây khung s s xxx cv 28 6.4.1 Bài toán cây khung - TH HH nh HH nen rgưên 28
6.4.2 Giới thiệu thuật toán Prim c c5 ccs<cccssecesee 29
6.4.3 Giới thiệu thuật toán KruskaÌ . sss cv vvvvsesssesseeke 30 6.4.5 Độ phức tạp ng ng ng ng xà 3l
Trang 66.5 Bài toán tìm chu trình Hamilton qua tất cả các đỉnh của dé thi 32
6.5.1 Phát biểu bài toán - ¿+ ccctcrtirrtsrrrrrrrirrrrrrrrirrerrrie 32 6.5.2 Giới thiệu thuật toán tìm chu trình Hamilton: . .- 33
Chương 2 MÔ PHÒNG THUẬT TOÁN . Gv xxx rerererererrree 34
1 Khái niệm và chức năng của mô phỏng - 55c 55 <<<<<<ccc<+ssssss 34
2 Lich sur cua m6 phong thuat toan cccccccecccccccaesececeeeeeeeeeeeeeeceeeeessaeeees 35
3 Hiệu quả của mô phỏng thuật toán trong giảng dạy . 37
4 Một số yêu cầu đối với mô phỏng thuật toán - s5 Sex: 41
4.1 Mô phỏng đúng theo thuật toán - cccccSSSSSccccsvessss 41 4.2 Cho phép thực hiện theo từng bước ca 41
4.3 Mô phỏng thuật toán phải có tính động - - 5c << <<<<<<<2 41 4.4 Có thể thực thi với mọi bộ dữ liệu đầu vào -ccccscc: 43
4.5 Có sự phân cấp người hỌC -c- cv 1E 1v xgxgkgvrvrereret 43
5 Quy trình mô phỏng thuật toán - << St skkkssssee 43 5.1 Nghiên cứu và phân tích giải thuật 555cc S332 43
5.2 Mô phỏng đữ liệu vào và kết quả đầu ra -c- sec: 44
5.3 Chia thuật toán thành nhiều bước nhỏ rồi mô phỏng theo từng bước 45 5.4 Tổng hợp mô phỏng theo các ĐưỚc ¿set SE cvcec: 47 5.5 Sơ đồ cấu trúc chung của hệ thống mô phỏng . 22s 52s c+s2 47
6 Đề xuất lựa chọn công cụ đề phát triển chương trình mô phỏng thuật toán 48 6.1 Một số hệ thông mô phỏng thuật toán chung .- 5s sẻ 49 6.2 Sử dụng công cụ mô phỏng thuật toán riêng biệt 52
6.3 Xây dựng hệ thống từ đầu - - - kề xnxx nưệt 53
Chuong 3 PHAN TICH THIET KE HE THONG MO PHONG MOT SO
THUAT TOÁN TRÊN ĐÔ THỊ, - G22 2+3 E2 EEEEEEEEEEEErrerrrrreee 54
I1 Mục đích - c ccc ng nu ng vết 54
2 Nhitng yéu cau thuc t6 oo ccceccceccccececescccscececcececsceceececevaceceuseevaveueevacaeeeees 54
3 Đề xuất cho hệ thỗng mớii - cv S113 1v ng ng ru 55
4 Thiết kế hệ thông mô phỏng một số thuật toán trên đồ thị 56
Trang 74.1 Lua chon cong cy lap trimh ec cecccceeccccccceceeeeesnsaeeeeeeeeeesseeeeeeeees 57
4.2 Chức năng mô phỏng của các thuật toán được cài đặt 59
4.2.1 Mô phỏng thuật toán tìm kiếm - tt xxx cee: s9
4.2.2 Mô phỏng thuật toán DIjkstra . - 5c cccs‡<<<<*c+ssssrsss 61 4.2.3 Mô phỏng thuật toán Ford — Bellman - 63 4.2.4 Mô phỏng thuật toán Prim -ccccccccS vs ssrrea 63 4.2.5 Mô phỏng thuật toán Kruskal -<<5<<<<<cc<s+sssssss 65
4.2.6 Thuật toán tìm chu trình HamiÌton c << << << << <2 66
5 Giới thiệu chương trình c ccc n3 n HT HH HH ng ng ng 66 5.1 Tông quan về hệ thống - tt v1 E111 8 5 1111118 se rrred 66
5.1.1 Các đối tượng xây đựng cấu trúc đồ thị, - sc+ssszszscxz 67
5.1.2 Cong cu vé hinh anh dé m6 phong ecccesceesssssesseeseseeseeesarees 70
5.1.3.Chức năng chỉ tiết của các công cụ hỗ trợ cho quá trình mô phỏng 70
5.2 Giới thiệu các công cụ hỗ trợ mô phỏng do người dùng cài đặt 71
Chuong 4 KET LUAN .eeccccccccescscscececececescecececcevevacecsceeceacaceesesarscaceusevacavacees 80
1 Những kết quả đạt ẨƯỢC - ch nề 1T ng ng ng ng 80
2 Hướng phát trign sce ccccecsceccsssceceseecscscecsevecsvacecessevecsesevavacseeseevevavaeees 81
DANH MUC TAI LIEU THAM KHAO c.ccsssssssssessesssessseseesseanseneaneaneesseses 82
PHU LUC oon 84
Trang 8LỜI NÓI ĐẦU
Cách đây gần ba thập kỉ (khoảng những năm 80 của thé ki XX), 6 nhiéu
nước trên thế giới mô phỏng thuật toán đã được sử dụng trong việc giảng dạy
các môn Khoa học máy tính như một công cụ hữu hiệu đề mô tả thuật toán một
cách trực quan, khoa học Không những vậy nó còn cho người học biết chỉ tiết từng bước hoạt động của thuật toán cùng với cấu trúc đữ liệu đi kèm thông qua việc mô tả băng đô họa
Những năm gần đây, ở Việt Nam môn Tin học đã được đưa vào chương
trình của học sinh trung học phố thông như là một môn học chính thức Tuy nhiên trên thực tế, một số trường chuyên trên cả nước đã tuyến sinh học sinh chuyên Tin từ cuỗi những năm 80 của thế kỉ XX Những học sinh này cần nam
chắc kiến thức cơ bản về Tin học như: các cầu trúc đữ liệu trừu tượng: stack,
queue, cây, cây nhị phân, cây nhị phân tìm kiếm, các chiến lược thiết kế thuật
toán: tham lam, quay lui, quy hoạch động Trong đó, lý thuyết về đồ thị và
thuật toán trên đồ thị là một lĩnh vực rộng và phức tạp Việc hiểu và cài đặt tốt
các thuật toán đó đòi hỏi thời gian và công sức rất lớn Hiện nay, việc truyền đạt
các thuật toán trên đồ thị cho học sinh chuyên Tìn gặp rất nhiều khó khăn Có
nhiều rất nhiều lý do: Các thuật toán đó khó hình dung, việc tổ chức dữ liệu cho
nó cũng phức tạp, thời gian giảng dạy trên lớp có hạn, tài liệu tham khảo có thể
tự đọc, tu hoc van còn it
Trong khuôn khổ đề tài này, chúng tôi xây dựng một chương trình nhằm
mô phỏng hoạt động của ba thuật toán giải ba bài toán cơ bản trên đồ thị theo
phân phối chương trình của Bộ Giáo dục với hai mục đích: để học sinh có thê dễ
đàng nắm bắt tư tưởng cũng như từng bước hoạt động cụ thể của các thuật toán,
để giáo viên có thể làm cho bài giảng về các thuật toán này trở nên để hiểu, dễ tiếp thu hơn
Nội dung luận văn được chia thành 3 chương:
Trang 9Chương I Những kiến thức cơ bản về thuật toán
Ở chương này, chúng tôi trích nêu khái niệm về bài toán và thuật toán
Các tính chất của thuật toán, xác định độ phức tạp của thuật toán .Cuỗi cùng,
chúng tôi giới thiệu ba thuật toán quan trọng trên đồ thị mà học sinh THPT sẽ
được học
Chương II Mô phỏng thuật toán
Chương này chúng tôi trình bày khái niệm mô phỏng, các chức năng của
mô phỏng và các vân đê liên quan như: lịch sử mô phỏng, nghiên cứu về hiệu quả của nó trong giảng dạy và một sô yêu cầu đôi với việc mô phỏng thuật toán nói chung
Chương III Phân tích thiết kế hệ thống mô phỏng một số thuật toán trên
đồ thị
Ở chương 3, chúng tôi trình bày về quá trình phân tích, thiết kế và xây
dựng hệ thống mô phỏng trên ba thuật toán: thuật toán tìm kiếm (tìm kiếm theo chiều sâu và tìm kiếm theo chiều rộng), thuật toán tìm đường đi ngăn nhất (thuật toán Dijsktra) và thuật toán tìm cây khung cực tiêu trên đồ thị vô hướng có trọng
số (thuật toán Prim)
Trang 10Chương 1 MỘT SÓ KIÊN THỨC CO’ BAN VE THUAT TOÁN
1 Khái niệm bài toán Tìn học
Trong phạm vi tin học, người ta quan niệm bài foán là một công việc nào
đó mà con người muốn máy tính thực hiện [xem 1]
Khi dùng máy tính để giải bài toán, ta cần quan tâm tới 2 vẫn đề: Dữ liệu
cần được đưa vào máy tính (Input) là gi va can lay ra (Output) thong tin gi? Noi
một cách khác, cho một bài toán 1a viéc m6 ta rd Input va Output cua bài toán
Van dé con lai là: Làm thế nào để từ Input ta có được Output?
2 Khái niệm thuật toán
Khác với Toán học (các yêu cầu của bài toán thường là chứng minh sự tồn
tại đáp án chứ không yêu cầu tìm một cách chỉ tiết để tìm ra đáp án đó), giải một
bài toán Tin học là việc đi tìm một lời giải cụ thể, tường minh dé dua ra Output của bài toán dựa trên Input đã cho Việc chỉ ra một cách tìm Output của bài toán
được gọi là một thuật toán Có nhiều cách phát biểu khái niệm về thuật toán
Dưới đây là cách phát biểu được chọn để đưa vào sách giáo khoa Tin hoc pho
thông:
Khái niệm về thuật toán: thuật toán là một dãy hữu hạn các thao tác được sắp xếp theo một trình tự nhất định để sau khi thực hiện dãy các thao tác đó, tie input ta cé output can tim [xem 1]
Trong lĩnh vực máy tính, cụm từ “thuật toán” đôi khi người ta ding bang một từ khác: “giải thuật”
Ví dụ về một thuật toán: Nhập vào một số nguyên dương N, kiểm tra số
đó có là số nguyên tô hay không?
Lời giải:
Input: Số nguyên đương N
Output: Có/không tương ứng với N có là nguyên tổ hay không?
Trang 11Ý tưởng: Một số nguyên gọi là nguyên tố khi nó chỉ có ước là 1 và chính
nó Từ định nghĩa suy ra:
- Nếu N = I thì thông báo là N không nguyên tổ rồi kết thúc;
- Nếu 1< N < 4 thì thông báo N là số nguyên tổ rồi kết thúc;
- Nếu N > 4 và không có ước trong khoảng từ 2 đến [/M] thì N là nguyên
Thuật toán: Có nhiều cách mô phỏng khác nhau Dưới đây là cách
mô phỏng thuật toán dạng liệt kê các bước:
Bước 1 Nhập số nguyên đương N;
Bước 2 Nếu N = l thì thông báo là N không nguyên tổ rồi kết thúc;
Bước 3 Nếu N < 4 thì thông báo N là số nguyên tô rồi kết thúc;
Bước 4 1 — 2;
Bước 5 Nếu ¡>[xM]® thì thông báo N là nguyên tố rồi kết thúc;
Bước 6 Nếu N chia hết cho ¡ thì thông báo N không nguyên tổ rồi kết
thúc;
Bước 7 ¡<— ¡+ I rồi quay lại bước 5;
3 Các tính chất của thuật toán
Dựa trên khái niệm về thuật toán và ví dụ ở trên ta thay cac thao tac trong
thuật toán phải được mô tả đủ chỉ tiết để một đôi tượng cứ tiễn hành thực hiện
theo đúng thứ tự các thao tác đó là có thể cho ra output đựa trên input tương
ứng Một thuật toán phải đảm bảo được các tính chất sau:
Tính xác định: Sau khi thực hiện một thao tác thì hoặc là thuật toán kết thúc hoặc là có đúng một thao tác xác định dé thực hiện tiếp theo
Trang 12Tinh dung đắn: Sau khi thực hiện thuật toán ta phải nhận được đúng
Output can tìm
Tính dừng: Thuat toan phai kết thúc sau một số hữu hạn lần thực hiện
Tính tong quat: Thuat toan la dung đắn với mọi bộ dữ liệu đầu vào của
bài toán
Tính hiệu quả:
- Hiệu quả về thời gian: Ta quan tâm tới thời gian cần thiết để thực
hiện xong thuật toán đó Thời gian đó phải nằm trong giới hạn cho phép
- Hiệu quả về không gian: Dung lượng bộ nhớ cần thiết để lưu trữ
các đối tượng như bộ Input, bộ Output, kết quả trung gian và chương trình
được đùng để thực hiện thuật toán
- Dễ cài đặt: thuật toán đó liệu có chuyển được thành chương trình
bằng một ngôn ngữ lập trình nào đó hay không
Trước khi xây dựng thuật toán cho một bài toán nào đó, trước tiên phải
xác định được Input và Output là gì, thử trên một số ví dụ cụ thê đề định hướng cho việc xây dựng thuật toan /xem 1]
4 Độ phức tạp và xác định độ phức tạp của thuật toán
Một thuật toán chỉ có thể giải một bài toán, nhưng một bài toán có thê giải
bằng nhiều thuật toán khác nhau Làm thế nào để lựa chọn một thuật toán tốt để giải một bài toán đã cho? Tất nhiên, người lập trình thường chọn thuật toán dễ
hiểu, dễ cài đặt Theo đó, chương trình viết ra ít có khả năng có lỗi, việc nâng
cấp chương trình đễ đàng và nhiều người có thể thực hiện được Nhưng nếu hiệu
quả của thuật toán (về mặt thời gian và không gian nhớ) là yêu cầu quan trọng thì cần chọn một thuật toán chạy nhanh và sử dụng tài nguyên có sẵn một cách
hiệu quả Như vậy dựa vào đầu dé co thé kết luận thuật toán này “nhanh” hơn thuật toán kia?
Trang 13Có một cách để biết được thuật toán nào nhanh hơn bằng cách viết các
chương trình bằng cùng một ngôn ngữ lập trình cho các thuật toán rồi so sánh trên các bộ Input giỗng nhau trên cùng một hệ thống để kết luận thuật toán nào
nhanh, thuật toán nào chậm Tuy nhiên cách này không chính xác và tôn nhiều
thời gian
Một cách khác để đánh giá thuật toán là dựa vào tiêu chí mỗi câu lệnh của chương trình nguồn sẽ thực hiện bao nhiêu lần trên một tập dữ liệu vào Việc
đánh giá đó không chỉ đánh giá, so sánh trong việc lựa chọn thuật toán mà còn
có thể hiệu chỉnh, cải tiễn thuật toán đã có tốt hơn Khi đánh giá thời gian thực
hiện thuật toán ta chú ý đặc biệt đến các phép toán mà số lần thực hiện không Ít
hơn các phép toán khác — ta gọi là phép toán tích cực của thuật toán
Cách đánh giá thời gian thực hiện thuật toán độc lập với hệ thong may
tính dẫn đến khái niệm về Độ phức tạp của thuật toán Thời gian thực hiện một
thuật toán băng chương trình máy tính phụ thuộc vào rất nhiều yếu tố Một yếu
tô cần chú ý nhất đó là kích thước của đữ liệu đầu vào Dữ liệu càng lớn thì thời
gian xử lý càng chậm Nếu gọi n là kích thước đữ liệu đưa vào thì thời gian thực
hiện của một thuật toán có thể biểu diễn một cách tương đôi như một hàm của n:
T(n) Thực tế, T(n) không những chỉ phụ thuộc vào kích thước n mà còn phụ
thuộc vào đặc tính, tình trạng thực tế của bộ đữ liệu đầu vào
Ví dụ, với thuật toán sắp xếp dãy số đã cho thành dãy tăng dân thì thời
gian sắp xếp còn phụ thuộc vào dãy đầu vào đã là đãy tăng dần, đấy được sinh ngẫu nhiên hay được sắp xếp theo thứ tự ngược lại Vì thế cần phải xem xét các trường hợp tốt nhất, trung bình và xấu nhất /Xem 2j
Việc xác định độ phức tạp của một thuật toán bất kỳ có thể rất phức tạp Tuy nhiên, trong thực tễ, đối với một số thuật toán ta có thể phân tích bằng một
số quy tặc đơn giản:
4.1 Quy tắc max
Trang 14Nếu thuật toán T có thời gian thực hién T(n) =O(f(n)+g(n)) thi cd thé coi
T1 có độ phức tạp là O(max(f(n), g(n)))
4.2 Quy tac tong
Néu thuat toan T gom hai doan thuat toan lién tiếp T1 và T2 và nếu T1 có
thời gian thực hiện T1(n) = O(f(n)), T2 có thời gian thực hiện là T2(n) = O(g(n)) thì thời gian thực hiện T sẽ là:
T(n) = T1(n) + T2(n) = O(f(n)+ g(n))
4.3 Quy tac nhan
Nếu đoạn chương trình T có thời gian thực hiện là T(n) = O(fn)) Khi đó,
nếu thực hiện k(n) lần đoạn chương trình T với k(n) = O(g(n)) thì độ phức tạp sẽ
la O(g(n).f(n))
4.4 Một số tính chất
Theo định nghĩa về độ phức tạp tính toán ta có một số tính chất:
a) Nếu một thuật toán có độ phức tạp là hằng số, tức là thời gian thực hiện
không phụ thuộc vào kích thước đữ liệu vào thì ta ký hiệu độ phức tạp tính toán của thuật toán đó là O(1)
b) Với một thuật toán có độ phức tạp cấp logarit của f(n), người ta ký hiệu
là O(logf(n)) ma không cần ghi cơ số của logarit
c) Với P(n) là một đa thức bậc k thì O(P(n)) = O(n*) Vì thế, một thuật
toán có độ phức tạp cấp đa thức, người ta thường ký hiệu là O(n)
đ) Một thuật toán có cấp là các hàm như 2", n!, n" được gọi là một thuật toán có độ phức tạp hàm mũ Những thuật toán như vậy trên thực tế thường có
tốc độ rất chậm Các thuật toán có cấp là các hàm đa thức hoặc nhỏ hơn hàm đa thức thì thường nhanh hơn các thuật toán hàm mũ Tuy nhiên, khi chọn một thuật toán để giải một bài toán thực tế phải có một sự mềm dẻo nhất định dựa
vào những điều kiện thực tế cho phép
Trang 15Dưới đây là một số hàm số hay dùng dé ky hiệu độ phức tạp tính toán và
bảng giá trị của chúng đê tiện theo dõi sự tăng của hàm theo đôi sô n
Với mỗi giá trị ¡ của vòng lặp 3, vòng lặp 3.2 thực hiện ¡ vòng lặp nên khi
n =1 nó thực hiện đủ n vòng lặp Vậy vòng lặp 3 thực hiện `" lần câu lệnh
sau do nên thời gian tính toán tỉ lệ thuận với nỶ,
Vậy độ phức tạp tính toán của thuật toán trên là O(n’)
Thuat toan 2: Vix" =x *x"" nén cé thé tan dung két qua cua lan tinh truéc cho lan tinh sau:
Trang 16Hai lệnh 2 và 4 đều có độ phức tạp tính toán là O(1) Vòng lặp 3 cần thực
hiện n lần hai thao tac tinh S và p Vậy số lần thực hiện lệnh 3 là 2ø Do vậy, độ
phức tạp tính toán của thuật toán trên là O(n)
5 Chỉ phí thực hiện thuật toán
Khái niệm độ phức tạp tính toán đặt ra là dé đánh giá chi phí thực hiện một thuật toán về mặt thời gian Nhưng chi phí thực hiện thuật toán còn có rất
nhiều yếu tố khác nữa: không gian bộ nhớ phải sử dụng là một ví dụ Tuy nhiên, trên phương diện phân tích lý thuyết, ta chỉ có thể xét tới vẫn đề thời gian bởi
việc xác định các chi phí khác nhiều khi rất mơ hồ và phức tạp Đối với người
lập trình thì khác, một thuật toán với độ phức tạp dù rất thấp cũng sẽ là vô dụng néu nhu không thể cài đặt được trên máy tính, chính vì vậy khi bắt tay cài đặt
một thuật toán, ta phải biết cách tổ chức dữ liệu một cách khoa học, tránh lãng
phí bộ nhớ không cần thiết Có một quy luật tương đối khi tô chức đữ liệu: Tiết
kiệm được bộ nhớ thì thời gian thực hiện thường sẽ chậm hơn và ngược lại Biết
cân đối, dung hoà hai yếu tố đó là một kỹ năng cần thiết của người lập trình [Xem 2]
6 Ba bai toan trén mô hình đô thi duoc dua vao giang day trong truéng
Trung học Phô thông Chuyên
6.1 Một số khái niệm cơ bản về đồ thị
6.1.1 Khái niệm đồ thị (Graph)
Là một câu trúc rời rạc gom các đỉnh và các cạnh nỗi các đỉnh đó Được
mô tả hình thức: G = (V, E) Trong đó:
Trang 17V gọi là tập các đỉnh (Vertices) và E gọi là tập các cạnh (Edges) Có thể coi E là tập các cặp (u, v) với u và v là hai đỉnh của V
6.1.2 Các khái niệm cơ bản
Có thê phân loại đồ thị theo đặc tính và số lượng của tập các cạnh E: Cho
đồ thị G = (V, E) Ta có một số khái niệm sau /xem 3- tập 1j:
Đơn đồ thị: G được gọi là đơn đồ thị nếu giữa hai đỉnh u, v của V có nhiều nhất
là 1 cạnh trong E nối từ u tới v
Đa đồ thị: G được gọi là đa đồ thị nếu giữa hai đỉnh u, v của V có thể có nhiều hơn 1 cạnh trong E nỗi từ u tới v
Đồ thị vô hướng: G được gọi là đồ thị vô hướng nếu các cạnh trong E là không
định hướng, tức là cạnh nối hai đỉnh u, v bất kỳ cũng là cạnh nỗi hai đỉnh v, u
Hay nói cách khác, tập E gồm các cặp (u, v) không tính thứ tự (u, v) = (v, u)
Đồ thị có hướng: G được gọi là đồ thị có hướng nếu các cạnh trong E là có định
hướng, có thể có cạnh nối từ đỉnh u tới đỉnh v nhưng chưa chắc đã có cạnh nối
từ đỉnh v tới đỉnh u Hay nói cách khác, tập E gồm các cặp (u, v) có tính thứ tự: (u, v) # (v, u) Trong đồ thị có hướng, các cạnh được gọi là các cung Đồ thị vô
Trang 18hướng cũng có thê coi là đô thị có hướng nêu như ta coi cạnh nôi hai đỉnh u, v bất kỳ tương đương với hai cung (u, v) và (v, u)
Đối với đồ thị vô hướng G = (V, E) Xét một cạnh e e E, nếu e = (u, v) thì
ta nói hai đỉnh u và v là kê nhau (adjacent) và cạnh e này liên thuộc (incident) với đỉnh u và đỉnh v
Với một đỉnh v trong đồ thị, ta định nghĩa bậc (degree) của v, ký hiệu
deg(v) là số cạnh liên thuộc với v Dễ thấy răng trên đơn đồ thị thì số cạnh liên thuộc với v cũng là số đỉnh kề với v
Đối với đồ thị có hướng G = (V, E) Xét một cung e e E, nếu e = (u, v) thì
ta nói u nối tới v và v nối từ u, cung e là đi ra khỏi đỉnh u và đi vào đỉnh v
Đỉnh u khi đó được gọi là đỉnh đầu, đỉnh v được gọi là đỉnh cuỗi của Cung e
Với mỗi đỉnh v trong đồ thị có hướng, ta định nghĩa: Bán bậc ra của v ký
hiệu deg (v) là số cung đi ra khỏi nó; bán bậc vào ký hiệu deg (v) là số cung đi
vào đỉnh đó
Trang 19Đường đi: Một đường di do dai & tr dinh u dén dinh v la day (u=X9, x),
vey Xe = V) thoả mãn (x¡, X¿.¡) e E (là 1 cạnh của đồ thị) với Vi: (0 < ¡ < k) Đỉnh
u gọi là đỉnh xuất phát, v gọi là đỉnh kết thúc của đường đi Đường đi không có cạnh nào đi qua hơn 1 lần gọi là đường đi đơn
Chu trình: Đường đi có đỉnh xuất phát trùng với đỉnh kết thúc gọi là chu trình tương tự ta có khái niệm chu trình đơn
6.2 Bài toán tìm kiếm trên đồ thị
6.2.1 Phát biểu bài toán
Cho đồ thị G = (V, E) và s và t là hai đỉnh của đồ thị
Yêu cầu: Hãy chỉ ra một đường đi từ s đến t (nếu có)
Vi dụ: Xét một đô thị vô hướng và một đô thị có hướng dưới đây:
Trên cả hai đồ thị, (1, 2, 3, 4) là đường đi đơn độ dài 3 từ đỉnh 1 tới đỉnh
4 Bởi (1, 2) (2, 3) và (3, 4) đều là các cạnh (hay cung
Lam sao dé duyét tất cả các đỉnh có thé đến được từ một đỉnh xuất phát
nào đó? Vẫn dé này đưa về một bài toán liệt kê mà yêu cầu của nó là không được bỏ sót hay lặp lại bất kỳ đỉnh nào Vì vậy, cần phải xây đựng những thuật toán cho phép duyệt một cách hệ thống các đỉnh, những thuật toán như vậy gọi
là những thuật toán tìm kiếm trên đồ thị Trong lý thuyết đồ thị, người ta quan
Trang 21
Trang 20tam dén hai thuat toan co ban nhất: thuật toán tìm kiếm theo chiều sâu và thuật toán tìm kiêm theo chiêu rộng
6.2.2 Giới thiệu thuật toán tìm kiếm DES và BFS
a Thuật toán tìm kiếm theo chiều sâu DES (Depth — First — Search)
Tư tưởng của thuật toán có thể trình bày như sau: Bắt đầu từ s, mọi đỉnh u
kề với s tất nhiên sẽ đến được từ s Với mỗi đỉnh u đó, những đỉnh v kề với u
cũng đến được từ s Y tưởng đó gợi ý cho ta viết một thủ tục đệ quy DES(u)
mô tả việc duyệt từ đỉnh u bằng cách thông báo thăm đỉnh u và tiếp tục quá trình
duyệt DES(v) với v là một đỉnh chưa thăm kề với u Để quá trình duyệt không
lặp lại bất kì đỉnh nào, ta dùng kỹ thuật đánh dẫu, khi thăm một đỉnh, ta sẽ đánh dấu đỉnh đó lại để các bước duyệt đệ quy kế tiếp không thăm lại đỉnh đó nữa
Vẫn đề còn lại: Để in ra được đường đi từ đỉnh xuất phát s, trong quá trình duyệt DFS(u), trước khi gọi đệ quy DFS(v) với v là một đỉnh kề với u mà chưa đánh dấu, ta lưu lại “vết” đường đi từ u tới v bằng cách đặt trace[v] := u, tức là trace[v] là đỉnh liền trước v trong đường đi từ s tới v Khi quá trình tìm kiếm theo chiều sâu kết thúc, đường đi từ S tới E sẽ là:
t«{ Trace[t] — — Trace[ui] < Trace[s| s
Truy ngược đường đi này sẽ cho ta hành trình đi từ s đến t Có thể mô tả thủ tục DFS dạng giả mã như sau:
Trace[v] := u; {Truy vết đường đi}
Trang 21
- Néu t chưa bị đánh dấu thì kết luận: Không có đường từ s->t>;
- Nếu t đã bị đánh dấu thì dựa vào Trace tìm đường đi từ s->t>;
>;
End
b Thuật toán tìm kiếm theo chiều rộng BES (Breadth — First — Search)
Ý tưởng của phương pháp cài đặt này là "lập lịch" duyệt các đỉnh Khi thăm một đỉnh ta sẽ lên lịch thăm tất cả 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) Ví dụ: Bắt đầu, ta
thăm đỉnh s Quá trình thăm S sẽ lên lịch duyệt những đỉnh (uị, ws, ., Up) ké voi
s (những đỉnh gần s nhất) Tiếp theo sẽ thăm đỉnh u, khi thăm u¡ sẽ lại lên lịch
duyệt những đỉnh (vị, V; ., Vạ) kề với u¡ Nhưng rõ ràng các đỉnh này "xa" s hơn
những đỉnh u nên chúng chỉ được duyệt đến khi tất cả những đỉnh u đã duyệt
xong Tức là thứ tự duyệt đỉnh sau khi đã thăm uụ sé 1a: (ua, U3 , Up, Vi, Vạ, ,
vạ) Do việc lập lịch như mô tả ở trên nên cần phải xếp hàng cho các đỉnh đã lên lịch theo đúng thứ tự Khi thêm đỉnh nào đó ta sẽ thêm vào cuối hàng (vì đỉnh lên lịch sau chắc chắn xa hơn các đỉnh đã lên lịch (vào hàng) rồi Chính vì nguyên tắc đó nên danh sách chứa những đỉnh đang chờ sẽ được tô chức dưới dạng hàng đợi (Queue)
Ta sẽ dựng giải thuật như sau:
Bước 1: Khởi tạo: free[s] = true; free[v] = false Vv eV\{s}
First:=l; Last:=l; Queue[Last]:=s;//Queue chi chtta s
Trang 22
Bước 2: Lặp cho tới khi Queue rỗng:
u := pop;//lay u khdi hang doi
free[u]:= false;
Xét Vv EV: néu v chua duoc tham:
Free[v] = £#alse;//đánh dẫu đã thăm Trace[v] = u;
Push(v);//đây v vào hàng đợi, chờ được thăm Bước 3: Truy vết tìm đường đi hoặc thông báo không thấy đường
6.2.3 Độ phức tạp tính toán của thuật toán DFS va 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 điễn đồ thị /xem 3 — tập 1J có ảnh hưởng lớn tới
chỉ 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 BES và DES đề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é thì độ phức tạp tính
toán trong trường hợp này là O(n + n’) = O(n’) 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
toan la O(n.m)
6.3 Bài toán tìm đường đi ngắn nhất trên đồ thị có trọng số
6.3.1 Phát biêu bài toán
Khái niệm đồ thị có trọng số: Đồ thị có trọng số là một bộ ba G = (V, E,
w) trong đó, G = (V, E) là đô thị, w là hàm được định nghĩa:
w:E -> R
ea wie)
Bài toán đó phát biểu đưới dạng tổng quát như sau: Cho đồ thị có trọng số
G=(V, E,w) 1a đồ thị không có chu trình âm
Trang 23Yêu câu: Hãy tìm một đường đi ngắn nhất (tổng trọng số qua các đỉnh
trên đường đi) từ đỉnh xuất phát s e V đến đỉnh đích t e V
Nếu như đồ thị có chu trình âm (chu trình với độ dài âm) thì khoảng cách
giữa một số cặp đỉnh nào đó có thể không xác định, bởi vì bằng cách đi vòng
theo chu trình này một số lần đủ lớn, ta có thể chỉ ra đường đi giữa hai đỉnh nào
đó trong chu trình này nhỏ hơn bất kỳ một số cho trước nào Trong trường hợp như vậy, có thể đặt vẫn đề tìm đường đi cơ bản (đường đi không có đỉnh lặp lại) ngăn nhất Vấn đề đó là một vấn đề hết sức phức tạp mà ta sẽ không bàn tới ở đây
Dưới đây, chúng tôi giới thiệu hai thuật toán giải bài toán này là thuật
toán Ford — Bellman và thuật toán Dijkstra
6.3.2 Giới thiệu thuật toán Ford - Bellman
Thuật toán Ford-Bellman có thê phát biêu rất đơn giản:
Với đỉnh xuất phát S Goi d(v) là khoảng cách từ S tới v
Ban đầu d(S) được khởi gán bằng 0 còn các d(v) với v # S được khởi gán bằng +
Sau đó ta tôi ưu hoá dần các d(v) như sau: Xét mọi cặp đỉnh u, v của đồ thị, nếu có một cặp đỉnh u, v mà d(v) > đ(u) + c(u, v) thì ta đặt lại d(v) := d(u) +
c(u, v) Tức là nếu độ đài đường đi từ S tới v lại lớn hơn tổng độ dài đường đi từ
5 tới u cộng với chi phí đi từ u tới v thì ta sẽ huỷ bỏ đường đi từ Š tới v đang có
và coi đường đi từ S tới v chính là đường đi từ S tới u sau đó đi tiếp từ u tới v Chú ý rằng ta đặt c[u, v] = + nếu (u, v) không là cung Thuật toán sẽ kết thúc
khi không thê tối ưu thêm bất kỳ một nhãn d[v] nào nữa
Tinh dừng của thuật toán:
Tại bước lặp 0: Bước khởi tạo d(S) = 0; d(v) := +eo với v # S: thi day d(v)
chính là độ đài đường đi ngăn nhất từ S tới v đi qua không quá 0 cạnh
Trang 24Giả sử tại bước lặp thứ ¡, đ(v) bằng độ dài đường đi ngắn nhất từ S tới v qua không quá ¡ cạnh, thì do tính chất: đường đi từ S tới v qua không quá i + l cạnh sẽ phải thành lập bằng cách: lẫy một đường đi từ S tới một đỉnh u nào đó
qua không quá ¡ cạnh, rồi đi tiếp tới v bằng cung (u, v) Nên độ đài đường đi
ngăn nhất từ S tới v qua không quá ¡ + 1 cạnh sẽ được tính bằng giá trị nhỏ nhất trong các giá trị: (Nguyên lý tối wu Bellman)
Độ đài đường đi ngắn nhất từ S tới v qua không quá ¡ cạnh
Độ dài đường đi ngăn nhất từ S tới u qua không quá ¡ cạnh cộng với trọng
số cạnh (u, v) (Vu)
Nên sau bước lặp tôi ưu các d(v) bằng công thức d(V)søc¡:¡ = min(đ(V)gưøc
„ đ(U)szøe¡+ c(u, v)) thì các d(v) sẽ bằng độ đài đường đi ngắn nhất từ S tới v qua
không quá 1 + 1 cạnh
Sau bước lặp tôi ưu thứ n - 1, ta có d(v) = độ dài đường đi ngắn nhất tir S
tới v qua không quá n - 1 cạnh Vì đồ thị không có chu trình âm nên sẽ có một đường đi ngắn nhất từ S tới v là đường đi cơ bản (qua không quá n - l cạnh)
Tức là d(v) sẽ là độ dài đường đi ngắn nhất từ S tới v
Vậy thì số bước lặp tối ưu hoá sẽ không quá n - 1 bước Nếu mỗi bước
Thì do sự tôi ưu bắc cầu (đùng đ(u) tối ưu d(v) rồi lại có thể dùng d(v) tôi
ưu d(w) nữa ) nên chỉ làm tốc độ tối ưu nhãn d(v) tăng nhanh lên chứ không thể giảm đi được
6.2.3 Giới thiệu thuật toán thuật toán Dijkstra
Thuật toán Dijkstra (E.Dijkstra - 1959) có thể mô tả như sau:
Trang 25Bước 1: Khoi tao
Với đỉnh v e V, gọi nhãn d[v] là độ đài đường đi ngắn nhất từ s tới v Ta
sẽ tính các đ[v] Ban đầu d[v] được khởi gán bằng w[s, v] Nhãn của mỗi đỉnh
có hai trạng thái tự do hay cô định, nhãn tự do có nghĩa là có thể còn tối ưu hơn
được nữa và nhãn cô định tức là d[v] da bang do dai duong di ngan nhất từ s tới
v nên không thê tối ưu thêm Để làm điều này ta có thể sử dụng kỹ thuật đánh
đấu: Free[v] = TRUE hay FALSE tuỳ theo d[v] tự đo hay cỗ định Ban đầu các
d[v] := min(d[v], d[u] + c[u, v])
Bước lặp sẽ kết thúc khi mà đỉnh đích t được cố định nhãn (tìm được
đường đi ngắn nhất từ s đến t); hoặc tại thao tác cô định nhãn, tất cả các đỉnh tự
do đều có nhãn là +œ (không tồn tại đường di)
Có thể đặt câu hỏi, ở thao tác 1, tại sao đỉnh u như vậy được cô định nhãn,
giả sử d[u] còn có thê tôi ưu thêm được nữa thì tất phải có một đỉnh t mang nhãn
tu do sao cho d[u] > d[t] + c[t, u] Do trọng số c[t, u] không âm nên d[u] > d[t],
trái với cách chọn d[u] là nhỏ nhất Tất nhiên trong lần lặp đầu tiên thì S là đỉnh
được cô định nhãn do đ[s] = 0
Bước 3: Kết hợp với việc lưu vết đường đi trên từng bước sửa nhãn, thông
báo đường đi ngắn nhất tìm được hoặc cho biết không tồn tại đường đi (d[t] =
+œ) Có thể mô tả ngắn gọn thuật toán bằng giả mã như sau:
Trang 26
Bước 2: Lặp nếu u z t (với u ¢ S)
2.1 Néu d[v] > d[u] + clu,v] thi
d[v] = min{d[v], d[u] + c[u, vị}
trace[v]=u (với v £ 5S - tập các đỉnh đã tối ưu) 2.2 Chọn v có d[ịv] nhỏ nhất //v=02 không có đường 2.3 Nếu v # 0 thi thêm v vào $5; u = v
Bước 3: In ra đường đi tối ưu từ s đến t hoặc thông báo
vô nghiệm
6.3.4 Độ phức tạp
Nếu đồ thị có nhiều đỉnh, ít cạnh, ta có thể sử dụng danh sách kể kèm
trọng số để biểu diễn đồ thị, tuy nhiên tốc độ của thuật toán Dijkstra vẫn khá
chậm vì trong trường hợp xấu nhất, nó cân n lần cô định nhãn và mỗi lần tìm
đỉnh để cô định nhãn sẽ mất một đoạn chương trình với độ phức tạp O(n) Vậy
độ phức tạp của thuật toán Dijkstra là O(n7) Đề tăng tốc độ, người ta thường sử
dụng cấu trúc đữ liệu Heap để lưu các đỉnh chưa cô định nhãn Heap ở đây là
một cây nhị phân hoàn chỉnh thoả mãn: Nếu u là đỉnh lưu ở nút cha và v là đỉnh lưu ở nút con thì d[u] < đ[v] (Đinh r lưu ở gốc Heap là đỉnh có đ[r] nhỏ nhất) 6.4 Các thuật toán tìm kiếm trên cây khung
6.4.1 Bài toán cây khung
Khái niệm cây khung: Cho đồ thị G = (V, E) vô hướng, liên thông và T =
(V,E') là một đồ thị con của G (E° c E) Khi đó, T được gọi là cây khung (cây
bao trùm) nếu T liên thông và không có chu trình đơn
Cho G = (V, E, w) là đồ thị vô hướng liên thông có trọng số, với một cây khung T của G, ta gọi trọng số của cây T là tổng trọng số các cạnh trong T
Yêu cầu: Trong số các cây khung của G, chỉ ra cây khung có trọng số nhỏ
nhất
Trang 27Cây khung như vậy được gọi là cây khung nhỏ nhất của đồ thị, và bài toán
đó gọi là bài toán xây dựng cây khung nhỏ nhất Dưới đây ta sẽ xét một trong
hai thuật toán thông dụng để giải bài toán cây khung nhỏ nhất của đơn đồ thị vô
hướng có trọng sô
6.4.2 Giới thiệu thuật toán Prim
Một trong hai thuật toán quan trọng để giải bài toán tìm cây khung nhỏ
nhất là thuật toán Prim Thuật toán đó có thể phát biểu hình thức như sau:
Đơn đồ thị vô hướng G = (V, E,w) Xét cây T trong G và một đỉnh v, gọi
khoảng cách từ v tới T là trọng số nhỏ nhất trong số các cạnh nối v với một đỉnh nào đó trong T:
d[v] = min{w[u, v] | ueT}
Ban đầu khởi tạo cây T chỉ gồm có mỗi đỉnh {1} Sau đó cứ chọn trong số
các đỉnh ngoài T ra một đỉnh gần T nhất, kết nạp đỉnh đó vào T đồng thời kết
nạp luôn cả cạnh tạo ra khoảng cách gần nhất đó Cứ làm như vậy cho tới khi:
Hoặc đã kết nạp được tất cả n đỉnh thì ta có T là cây khung nhỏ nhất
Hoặc chưa kết nạp được hết n đỉnh nhưng mọi đỉnh ngoài T đều có khoảng cách tới T là +œ Khi đó đồ thị đã cho không liên thông, ta thông báo việc tìm cây khung thất bại
Về mặt kỹ thuật cài đặt, ta có thể làm như sau:
Sử dụng mang đánh dấu Free Free[v] = TRUE nếu như đỉnh v chưa bị kết nạp vào T
Gọi d[v] là khoảng cách từ v tới T Ban đầu khởi tạo đ[1] = 0 còn đ[2] =
d[3] = = d[n] = +00 Tai m6i buéc chon đỉnh đưa vào T, ta sẽ chọn đỉnh u nào
ngoài T và có d[u] nhỏ nhất Khi kết nạp u vào T rồi thì rõ ràng các nhãn d[v] sẽ thay đôi: d[v]mới := min(d[v]cũ, vịu, v]) Vẫn đề chỉ có vậy (chương trình rất giống thuật toán Dijkstra, chỉ khác ở công thức tôi ưu nhãn)
Trang 28Có thể mô tả thuật toán Prim bằng đoạn giả mã sau:
Thuật toán Kruskal dựa trên mô hình xây dựng cây khung bằng thuật toán hợp nhất [xxx], chỉ có điều thuật toán không phải xét các cạnh với thứ tự tuỳ ý
mà xét các cạnh theo thứ tự đã sắp xếp: Với đô thị vô hướng G = (V, E) có n
đỉnh Khởi tạo cây T ban đầu không có cạnh nào Xét tất cả các cạnh của đồ thị
từ cạnh có trọng số nhỏ đến cạnh có trọng số lớn, nếu việc thêm cạnh đó vào T
không tạo thành chu trình đơn trong T thì kết nạp thêm cạnh đó vào T Cứ làm như vậy cho tới khi:
Hoặc đã kết nap duoc n - Ïl cạnh vào trong T thì ta được T là cây khung
nhỏ nhất
Hoặc chưa kết nạp đủ n - I cạnh nhưng hễ cứ kết nạp thêm một cạnh bất
kỳ trong số các cạnh còn lại thì sẽ tạo thành chu trình đơn Trong trường hợp
này đồ thị G là không liên thông, việc tìm kiếm cây khung thất bại
Như vậy có hai vấn đề quan trọng khi cài đặt thuật toán Kruskal:
Thứ nhất, làm thế nào để xét được các cạnh từ cạnh có trọng số nhỏ tới cạnh có trọng số lớn Ta có thể thực hiện bằng cách sắp xếp danh sách cạnh theo thứ tự không giảm của trọng số, sau đó duyệt từ đầu tới cuối danh sách cạnh
Trang 29Nên sử dụng các thuật tốn sắp xếp hiệu qua dé đạt được tốc độ nhanh trong trường hợp số cạnh lớn Trong trường hợp tơng quát, thuật tốn HeapSort là hiệu quả nhất bởi nĩ cho phép chọn lần lượt các cạnh từ cạnh trọng nhỏ nhất tới cạnh trọng số lớn nhất ra khỏi Heap và cĩ thê xử lý (bỏ qua hay thêm vào cây) luơn
Thứ hai, làm thế nào kiểm tra xem việc thêm một cạnh cĩ tạo thành chu
trình đơn trong T hay khơng Đề ý rằng các cạnh trong T ở các bước sẽ tạo thành một rừng (đồ thị khơng cĩ chu trình đơn) Muốn thêm một cạnh (u, v) vào T mà khơng tạo thành chu trình đơn thì (u, v) phải nối hai cây khác nhau của rừng T, bởi nếu u, v thuộc cùng một cây thì sẽ tạo thành chu trình đơn trong cây đĩ Ban
đầu, ta khởi tạo rừng T gồm n cây, mỗi cây chỉ gồm đúng một đỉnh, sau đĩ, mỗi
khi xét đến cạnh nỗi hai cây khác nhau của rừng T thì ta kết nạp cạnh đĩ vào T,
đồng thời hợp nhất hai cây đĩ lại thành một cây
6.4.5 Độ phức tạp
Xét về độ phức tạp tính tốn, thuật tốn Prim cĩ độ phức tạp là O(n'
Tương tự thuật tốn Dijkstra, nếu kết hợp thuật tốn Prim với cấu trúc Heap sẽ
được một thuật tốn với độ phức tạp O((m+n)lòn)
Đối với thuật tốn Kruskal, ta cĩ thể chứng minh được rằng thao tác GetRoot cĩ độ phức tạp là O(log2n), cịn thao tác Union là O(1) Giả sử ta đã cĩ danh sách cạnh đã sắp xếp rồi thì xét vịng lặp dựng cây khung, nĩ duyệt qua
danh sách cạnh và với mỗi cạnh nĩ gọi 2 lần thao tác GetRoot, vậy thì độ phức
tạp là O(nlog2n), nếu đồ thị cĩ cây khung thì m > n-1 nén ta thay chi phi thoi gian chủ yếu sẽ nằm ở thao tác sắp xếp danh sách cạnh bởi độ phức tạp của HeapSort là O(mlog2m) Vậy độ phức tạp tính tốn của thuật tốn là O(mlog2m) trong trường hợp xấu nhất Tuy nhiên, phải lưu ý rằng để xây dựng cây khung thi ít khi thuật tốn phải duyệt tồn bộ danh sách cạnh mà chỉ một phần của danh sách cạnh mà thơi
Trang 306.5.Bài toán tìm chu trình Hamilton qua tất cả các đỉnh của đô thị
6.5.1 Phát biểu bài toán
Khái niệm chu trình Hamilton: Cho đồ thị G = (V, E) có n đỉnh
Chu trình (xị, xạ, ., Xạ, xị) được gọi là chu trình Hamilton nếu x¡ # xị với
I<i<jJ<n
Đường đi (xị, Xa, ., xạ) được gọi là duong di Hamilton néu x; 4 xj VO11 < i<j<n
Có thê phát biểu một cách hình thức: Chu trình Hamilton là chu trình xuất
phát từ 1 đỉnh, đi thăm tất cả những đỉnh còn lại mỗi đỉnh đúng 1 lần, cuối cùng
quay trở lại đỉnh xuất phát Đường đi Hamilton là đường đi qua tất cả các đỉnh
của đồ thị, mỗi đỉnh đúng I lần
Bài toán tìm chu trình Hamilton: Cho đồ thị G = (V, E) có n đỉnh, m cạnh
Yêu cầu: Hãy chỉ ra một chu trình Hamilton của đồ thị đã cho
Đề tìm chu trình Hamilton, ta quan tâm đến các định lý sau:
Dinh ly 1: Đồ thị vô hướng G, trong đó tồn tại k đỉnh sao cho nếu xoá đi k đỉnh này cùng với những cạnh liên thuộc của chúng thì đồ thị nhận được sẽ có
nhiều hơn k thành phần liên thông Thì khăng định là G không có chu trình
Hamilton Mệnh đề phản đảo của định lý này cho ta điều kiện cần để một đồ thị
có chu trình Hamilton
Định lý 2 (Định lý Dirac (1952)): Đồ thị vô hướng G có n đỉnh (n > 3)
Khi đó nếu mọi đỉnh v của G đều có deg(v) > n/⁄2 thì G có chu trình Hamilton Đây là một điều kiện đủ để một đồ thị có chu trình Hamilton
Định lý 3: Đồ thị có hướng G liên thông mạnh và có n đỉnh Nếu
deg' (y)> „và deg' (v)> 2 với mọi đỉnh v thì G có chu trình Hamilton
Trang 316.5.2 Gidi thiéu thuat toan tim chu trinh Hamilton:
Dưới đây ta sẽ cài đặt một chương trình liệt kê tất cả các chu trình
Hamilton xuất phát từ đỉnh 1, các chu trình Hamilton khác có thể có được bằng
cách hoán vị vòng quanh Lưu ý rằng cho tới nay, người ta vẫn chưa tìm ra một phương pháp nào thực sự hiệu quả hơn phương pháp quay lui để tìm dù chỉ một chu trình Hamilton cũng như đường đi Hamilton trong trường hợp đồ thị tông
quát
2.1 u = đỉnh vừa thăm xong
Trang 32Chuong 2 MO PHONG THUAT TOAN
I, Khai niém và chức năng của mô phỏng
Mô phỏng thuật toán là quá trình mô tả câu trúc đữ liệu, các thao tác của một chương trình bằng đồ hoạ [Stasko 1990] Mô phỏng thuật toán được thiết kế
nhằm giúp người dùng hiểu thuật toán, đánh giá thuật toán và gỡ lỗi khi cài đặt
chương trình (xem 12]
Một chương trình lập trình trên máy tính sẽ chứa các cấu trúc đữ liệu của
thuật toán mà nó sẽ thực hiện Trong khi thực hiện chương trình đó, giá trỊ thực
của cấu trúc đữ liệu thay đổi dựa trên từng bước hoạt động của thuật toán Mô
phỏng thuật toán sử dụng đồ hoạ để biểu diễn sự thay đổi trạng thái của câu trúc
dữ liệu cho từng bước hoạt động của nó một cách trực quan, khoa học Trong
suốt quá trình biểu diễn, người dùng có thể quan sát việc thực thi thuật toán theo từng bước để có thê biết chỉ tiết về thuật toán cũng như hiểu một cách tường tận
về thuật toán đó
Ví dụ: Một chương trình mô phỏng thuật toán phân tích LR phân tích trên
1 chuỗi kí tự Chương trình chứa ba cầu trúc: bảng chuyển, một ngăn xếp (stack)
và 1 xâu kí tự Khi thực hiện, chương trình minh hoạ bằng việc đối sánh các
trạng thái trong bảng chuyến và và thực hiện từng thao tác trên ngăn xếp đề tách xâu kí tự Các chỉ dẫn, kí hiệu trên xâu vào và các phần tử trong ngăn xếp ở mỗi
trạng thái sẽ lần lượt thay đổi trong khi thực hiện thuật toán Đây là một công việc khá khó khăn để nắm bắt nếu một học sinh chỉ sử dụng hình vẽ và các xâu
kí tự Mô phỏng thuật toán có thể chỉ ra tất cả các thông tin và sự thay đôi đồng thời ở từng bước băng đồ hoạ Ta có thể quan sát bằng hình vẽ đưới đây:
Trang 33Grammar 3->a
gS-*b String: aabbb Current Stata 2
Hinh 1 M6 phỏng một bước hoạt động của thuật toán
Bên cạnh việc giúp người dùng hiểu rõ thuật toán, mô phỏng thuật toán
cũng có thê dùng để gỡ lỗi chương trình một cách dễ dàng hơn Để sử dụng mô
phỏng thuật toán trong việc gỡ lỗi, người dùng ghi chú các trạng thái thực trên chương trình của họ để đưa ra các lệnh mô phỏng đầu ra và những bước làm cho thuật toán không cho ra kết quả như mong muốn
2 Lịch sử của mô phỏng thuật toán
Năm 1981 Ronald Baecker tại đại học Toronto đã thiết kế đoạn video
“Sorting Out Sorting” Day là mốc đánh dấu sự phát triển của lĩnh vực mô phỏng Từ đó, các giảng viên đã sử dụng hệ thống mô phỏng để giảng dạy các
môn thuật toán Từ những năm 1980 đến đầu những năm 90 của thế kỉ XX, có 2
hệ thông được phát triển đã gây ảnh hưởng đến tất cả những hệ thông về sau đó
là BALSA-I (Brown ALgorithm Simulator and Animator) [Brown 1984] va TANGO (Transition-based Animation GeneratiOn) [Stasko 1990]
BALSA - I là hệ thông mô phỏng thuật toán nỗi tiếng được biết đến đầu tiên, được viết bởi giáo sư Marc Brown và Robert Sedgewick (Đại học Brown — My) BALSA — I là chương trình mô phỏng thuật toán tương tác Nó đưa ra
Trang 35
Trang 34nhiéu khung nhin về câu trúc đữ liệu và có thê thực hiện nhiều thuật toán một
cách đồng thời Sự phát triển của nó là động lực thúc đây các nghiên cứu khác trong lĩnh vực này
Một hệ thong khac, TANGO, do John Stasko (Dai hoc Brown — My) viết
vào đầu những năm 90 Điểm nỗi bật của hệ thống này là giới thiệu mô hình
chuyến cho thiết kế mô phỏng va framework cho hệ thông mô phỏng thuật toán
Nó giới thiệu một khái niệm mới về famework (sau này có rất nhiều hệ thông
sử dụng nó như một cầu trúc cơ bản)
Từ khi hai hệ thống này được công bố, các hệ thống con của nó cũng
được phát triển BALSA — II (1988) TANGO có rất nhiều phiên bản Một trong
số đó là XTANGO và POLKA POLKA được thiết kế cho các thuật toán chạy
song song Nó là hệ thông mô phỏng thuật toán 2D hướng đối tượng và mở rộng trong 3D, POLKA 3D POLKA 3D cung cấp cách nhìn 3D và các cơ sở như
góc, hình cầu, hình khối Người đùng không yêu cầu phải biết kiến thức về đồ
họa 3D đề sử dụng POLKA 3D SAMBA là hệ thông mô phỏng tương tác thông dịch, nó đọc các lệnh ASCII và thực hiện các thao tác mô phỏng tương ứng Phiên bản của SAMBA cài bằng Java và có thể xem chỉ tiết tại trang web http://www.cc gatech.due/gvu/softviz/parviz/samba.html
Một số hệ thống mô phỏng nỗi tiếng khác là Zeus, Leonardo, CATAI,
Mocha Zeus (Brown 1991) được phát triển tại đại học Brown cùng với hệ thong
BALSA va BALSA - II No duoc coi la phan mém tương tác trực quan hóa Nó
hỗ trợ việc đồng bộ các khung nhìn và cho phép người dung chỉnh sửa các
khung nhìn này và thay đổi biểu diễn của dữ liệu Zeus được thực thi trong môi
trường đa xử lý và đa tuyến, nó cũng cho phép thực thi các thuật toán song song Leonardo là hệ thống mô phỏng các chương trình C Nó tích hợp phát triển với
mô phỏng của các chương trình C vào cùng một môi trường CA TAI mô phỏng các chương trình C++ Nó dựa trên kĩ thuật đối tượng phân phối và cho phép nhiều người dùng chia sẻ cùng một mô phỏng thông qua “lớp” ảo Việc giao tiếp
Trang 35va đồng bộ giữa các trạm và thuật toán được mô phỏng được đảm bảo bởi server
có sử dụng kĩ thuật CORBA Mocha là mô hình phân phối với kiến trúc client —
server, nó phân đoạn một cách tôi ưu các thành phần của hệ thống mô phỏng thông thường Nó vượt qua các tồn tại của X - window và mô hình Java Trong
mô hình Mocha chỉ có mã giao diện được xuất tới máy của người dùng Khi
thuật toán chay trên server thì đoạn mã giao diện lại chạy trên máy người dùng
Hiện tại, một số lượng lớn các chương trình mô phỏng đã được viết ra
Hầu hết trong số chúng rất phô biến và sử dụng phức tạp Các phần mềm này
được thiết kế nhằm mục đích giáo dục hoặc các nghiên cứu Một vài chương
trình có cầu trúc phức tạp và yêu cầu hỗ trợ kĩ thuật cao Rõ ràng, điều này ít
thực tế, chung ta mong muốn một phần mềm nhỏ gọn và linh hoạt, có cầu trúc
đơn giản
Ÿ Hiệu quả của mô phóng thuật toún trong giảng dạy
Trên thế giới, hệ thông mô phỏng đã được sử dụng rộng rãi trong việc
dạy học ngành khoa học máy tính Đã có một số lượng các sinh viên được đào
tạo bằng các chương trình mô phỏng để thấy được hiệu quả của nó trong giảng đạy nhưng kết quả rất khác nhau Có thể đưa ra một vài ví dụ như sau:
Giáo sư Brown (Đại học Brown) năm 1984 đã sử dụng phần mềm
BALSA - I để dạy môn học lập trình và môn cẫu trúc dữ liệu và giải thuật Hệ
thống này sử dụng để trực quan hóa chương trình dạy học Ông viết trong bản báo cáo rằng việc sử dụng các đoạn mô phỏng kèm vào các bài giảng là một
chứng minh cho việc “tốc độ hiểu bài của học sinh tăng lên” so với cách giảng
dạy truyền thống
Stasko (Dai hoc Brown) nam 1997 sử dụng SAMBA - chương trình mô phỏng của hệ thống XTANGO dé dạy môn thuật toán Ông yêu cầu các sinh viên sử dụng hệ thông để thêm vào các mô phỏng của chính bài tập của mình Kêt quả chỉ ra rằng sinh viên râầt có hứng thú với các chương trình mô phỏng và
Trang 36chính chương trình mô phỏng đã khuyến khích sự sáng tạo của học sinh Rõ ràng, nhờ có chương trình mô phỏng mà các sinh viên hiểu các thuật toán nhanh
hơn, nhớ được lâu hơn
Tuy nhiên, việc sử dụng chương trình mô phỏng trong dạy học không phải lúc nào cũng đem lại kết quả tốt Stasko (1993) đã thử nghiệm đạy 2 nhóm
sinh viên với cùng một nội dung bài học về HEAP — một dạng cấu trúc đữ liệu
trừu tượng Một nhóm học thuật toán dựa trên mô tả một cách khái niệm Nhórmn
còn lại học bài đựa trên chương trình mô phỏng tương tác Mặc dù kết quả cho thay nhóm được học có mô phỏng điểm cao hơn nhóm còn lại nhưng sự chênh lệch không đủ đề thấy được lợi ích của việc mô phỏng Tương tự, Byrne (1996) cũng làm 2 thí nghiệm tương tự và kết quả thu được cũng không chỉ rõ được lợi ích của việc mô phỏng
Mặc đầu vậy, những kết quả đó không làm cho việc mô phỏng thuật toán mất đi những điểm mạnh của nó mà nó hướng người dùng đến một cách nhìn khác về thuật toán mô phỏng Kết quả chỉ ra răng để đạt được hiệu quả tỗi ưu khi dùng thuật toán mô phỏng là dùng nó như một cầu nối với các nhân tô khác Lawrence đã sử dụng hệ thống XTANGO và POLKA để giảng dạy về thuật toán
Kruskal Tất cả sinh viên của nhóm học có mô phỏng có tác động rõ rệt Thực
nghiệm cũng cho thấy răng để người học tiếp thu nhanh hơn thì nên để cho họ tự
học và tự tạo cho mình tập đữ liệu hơn là các dữ liệu do giáo viên tự chuẩn bị từ trước
Hơn nữa, năm 1999 nghiên cứu của giáo sư Kehoe chỉ ra tính hiệu quả của việc sử dụng mô phỏng trong giảng dạy thuật toán bằng cách chia học viên
thành các nhóm đề dạy vé thuat toan BINOMIAL HEAP — mot dang cầu trúc đặc biệt của HEAP Một nhóm tự học thuật toán bằng cách dùng phần mềm mô phỏng, một nhóm học bằng cách đọc sách có các hình vẽ mô tả Kết quả chỉ ra
rang nhóm học qua phần mềm có khả năng cài đặt thuật toán tốt hơn nhóm còn
Trang 37lại (nhưng không phải là tất cả các thành viên đều như vậy) và họ nói răng nhờ
có mô phỏng mà họ có thể hiểu thuật toán nhanh hơn
Báo cáo của Kehoe chứng minh rằng cách hiệu quả để sử dụng thuật toán
mô phỏng trong việc dạy học có thê đạt được kết quả cao hơn đó là sử dụng nó
như là một hệ thông “mở” và hướng tự học (như là giao bài tập về nhà chẳng
hạn) Như vậy, việc mô phỏng thuật toán hiệu quả ở chỗ coi nó là một tài liệu học được sử dụng cùng với các tài liệu khác cùng với các hướng dẫn về cách
thức hoạt động của chương trình tương ứng với các thao tác của thuật toán Bài
bảo cũng chỉ ra rang mô phỏng thuật toán là một cách thuận lợi cho việc học
cách thức hoạt động của thuật toán Nếu như mô phỏng không phải lúc nào cũng
tạo điều kiện thuận lợi cho việc học tập tốt thì ít nhất nó có thể chỉ ra rằng một
thuật toán cần học có thể dễ tiếp cận hơn
Giáo sư Stasko cũng chỉ ra rằng cần có một vài điều kiện để thuật toán mô
phỏng có hiệu quả hơn trong giảng dạy Một trong những điều kiện đó là kết
hợp mô phỏng thuật toán với các trích dẫn giải thích cho dễ hiểu (chú thích),
việc mô phỏng sẽ hiển thị cùng với các mô tả một cách hình thức về các thao tác
đó Một điều kiện nữa là hệ thống mô phỏng thuật toán nên có khả năng chạy lại (replay) cho phép người dùng quan sát các thao tác quan trọng Một vài chương
trình có thê chỉ ra trạng thái trước, trạng thái sau Thêm vào đó, các phản hồi từ
phía người học cũng rất cần thiết để cải tiễn chương trình mô phỏng cho tốt hơn
Mặc dù kết quả thực nghiệm chỉ ra rằng không phải lúc nào mô phỏng cũng mang lại lợi ích tốt nhưng nó cũng không chỉ ra rằng mô phỏng không mang lại hiệu quả trong giảng dạy Trên thực tế, có những nghiên cứu chỉ ra tính không hiệu quả của một chương trình mô phỏng nhưng điều đó không làm cho
việc mô phỏng mất đi tính ưu việt mà là một cách để ta phải xem lại chương
trình đó, cải tiến chương trình đó cho nó hiệu quả hơn với người học
Trang 38Tom lại, để một chương trình mô phỏng có hiệu quả và mang lại lợi ích cho người học thì việc thiết kế và phát huy tính động trong chương trình là một yếu tô rất quan trọng Các tính chất sau đây cũng là cần thiết:
Truy cập mở: Người học có thể tự do truy cập vào các hệ thống mô
phỏng Đó là, bên cạnh việc có truy cập vào các hệ thông ở trường học, họ có
thé truy cập vào hệ thống từ nhà hoặc bất cứ nơi nào khác khi họ cần đến
Chủ động diều khiển mô phỏng: Người học sẽ có thê tạo ra bộ đữ liệu
của riêng mình khi sử dụng hệ thong Trong khi tự định nghĩa bộ dữ liệu vào
cũng có thể giúp đỡ học sinh xây dựng sự hiểu biết ban đầu, hệ thống nên có cả
hai lựa chọn: tự xây dựng đữ liệu hoặc dùng bộ dữ liệu vào mặc định của hệ thống
Khả năng tương tác giữa người học và hệ thống: Hệ thông mô phỏng phải có khả năng tương tác với người học, nghĩa là cho phép người học xem được kết quả, cho phép đừng thuật toán ở bất cứ thời điểm nào để quan sát, xem
lại đữ liệu ban đầu và chạy tiếp, chạy từng bước, huỷ, quay lại, chạy nhanh, chạy
chậm để thuật toán cho ra kết quả mong muốn Tương ứng với câu lệnh giả mã
mô tả thuật toán sẽ là bước mô phỏng trên đồ thị do người học tự mô tả
Đón nhận thông tin phản hồi: Hệ thông ghi nhận lại những góp ý từ
người học đê dân dân cải tiên hệ thông cho hiệu quả hơn
Các hệ thống mô phỏng thuật toán có nền tảng phụ thuộc nhau Với sự tiến bộ của công nghệ mới, sự phố dụng của WWW và sự phát triển của ngôn ngữ Java, các nhà lập trình chuyển sang lĩnh vực mô phỏng thuật toán trực tuyến trên mạng Một vài lập trình viên kết hợp cả đa phương tiện vào chương trình của họ Việc sử dụng hệ thông mô phỏng thuật toán đã giải quyết triệt để các
yếu điểm của cách dạy học truyền thống và có thể đảo tạo từ xa
Trang 394 Một số yêu cẩu đối với mô phỏng thuật toán
4.1 Mô phỏng đúng theo thuật toán
Để mô phỏng một thuật toán nào đó, các bước thực hiện chỉ dẫn trên đồ
họa phải phản ánh đúng theo nội dung của thuật toán đã đưa ra để đảm bảo rang người học học đúng thuật toán mình yêu cầu
4.2 Cho phép thực hiện theo từng bước
Thông thường, khi học một thuật toán phải dùng đến chương trình mô
phỏng để minh họa trong lúc học tập hoặc nghiên cứu thì thuật toán đó thường
không phải là thuật toán đơn giản Vì vậy, việc để cho người dùng có thể hiểu
được thuật toán thông qua chương trình mô phỏng thì chương trình đó phải hết sức “mềm dẻo”: ngoài việc cho phép người dùng đưa đữ liệu vào đúng theo chuẩn bị của họ thì nó còn có thể cho phép chạy thuật toán theo từng bước đề họ
có thể tiện theo dõi quá trình thay đôi dữ liệu cũng như kết quả của thuật toán
sau mỗi bước thực hiện Ngoài ra, chương trình càng hiệu quả hơn nếu nó cho
phép quan sát lại các bước đã thực hiện
4.3 Mô phóng thuật toán phải có tính động
Vì công việc của mô phỏng là mô tả sự thay đổi về cẫu trúc đữ liệu sau mỗi bước thực hiện của thuật toán nên hình ảnh mô phỏng câu trúc đó cũng phải thay đôi theo từng bước đề người học nắm bắt được ý tưởng của thuật toán
Ví dụ: với việc mô phỏng thuật toán tìm kiếm theo chiều rộng, cứ mỗi
bước thực hiện xong thuật toán thì hình ảnh mô phỏng cũng phải thay đối theo
Trong quá trình thực hiện thì đỉnh nào được chọn để xử lý sẽ có thông báo tại
đỉnh đó để người dùng quan sát cho dễ Dưới đây là hình ảnh trước và sau khi
một bước thuật toán được thực hiện