Thuật toán và phân tích thuật toán
Chơng I Thuật toán phân tích thuật toán 1.1 Tht to¸n 1.1.1 Kh¸i niƯm tht to¸n Tht to¸n (algorithm) khái niệm quan trọng tin học Thuật ngữ thuật toán xuất phát từ nhà to¸n häc A rËp Abu Ja'far Mohammed ibn Musa al Khowarizmi (khoảng năm 825) Tuy nhiên lúc nhiỊu thÕ kû sau, nã kh«ng mang néi dung nh ngày quan niệm Thuật toán tiếng nhất, có từ thời cổ Hy lạp thuật toán Euclid, thuật toán tìm ớc chung lớn hai số nguyên Có thể mô tả thuật toán nh sau : ThuËt to¸n Euclid Input : m, n nguyên dơng Output : g, ớc chung lớn m n Phơng pháp : Bớc : Tìm r, phÇn d cđa phÐp chia m cho n Bíc : NÕu r = O, th× g ← n (gán giá trị n cho g) dừng lại Trong trờng hợp ngợc lại (r 0), m n, n r quay lại bớc Chúng ta quan niệm bớc cần thực để làm ăn, đợc mô tả sách dạy chế biến ăn, thuật toán Cũng xem bớc cần tiến hành để gấp đồ chơi giấy, đợc trình bầy sách dạy gấp đồ chơi giấy, thuật toán Phơng pháp thực phép cộng, nhân số nguyên, đà học cấp I thuật toán Trong sách cần đến định nghĩa không hình thức thuật toán : Thuật toán dÃy hữu hạn bớc, bớc mô tả xác phép toán hành động cần thực hiện, để giải số vấn đề (Từ điểm Oxford Dictionary định nghĩa, Algorithm: set of well - defined rules for solving a problem in a finite number of steps.) Định nghĩa này, tất nhiên, chứa đựng nhiều điều cha rõ ràng Để hiểu đầy đủ ý nghĩa khái niệm thuật toán, nêu đặc trng sau thuật toán (Xem D.E Knuth [1968] The Art of Computer Programming, vol I Fundamental Algorithms) Input Mỗi thuật toán cần có số (có thể không) liệu vào (input) Đó giá trị cần đa vào thuật toán bắt đầu làm việc Các liệu cần đợc lấy từ tập hợp giá trị cụ thể Chẳng hạn, thuật toán Euclid trên, m n liệu vào lấy từ tập số nguyên dơng Output Mỗi thuật toán cần có nhiều liệu (output) Đó giá trị có quan hệ hoàn toàn xác định với liệu vào kết sù thùc hiƯn tht to¸n Trong tht to¸n Euclid cã liệu ra, g, thực đến bớc phải dừng lại (trờng hợp r = 0), giá trị g ớc chung lớn m n Tính xác định Mỗi bớc thuật toán cần phải đợc mô tả c¸ch chÝnh x¸c, chØ cã mét c¸ch hiĨu nhÊt Hiển nhiên, đòi hỏi quan trọng Bëi v×, nÕu mét bíc cã thĨ hiĨu theo nhiỊu cách khác nhau, liệu vào, ngêi thùc hiƯn tht to¸n kh¸c cã thĨ dÉn đến kết khác Nếu ta mô tả thuật toán ngôn ngữ thông thờng, ®¶m b¶o ngêi ®äc hiĨu ®óng ý cđa ngêi viÕt thuật toán Để đảm bảo đòi hỏi này, thuật toán cần đợc mô tả ngôn ngữ lập trình (ngôn ngữ máy, hợp ngữ ngôn ngữ bậc cao nh Pascal, Fortran, C, ) Trong ngôn ngữ này, mệnh đề đợc tạo thành theo qui tắc cú pháp nghiêm ngặt có ý nghĩa Tính khả thi Tất phép toán có mặt bớc thuật toán phải đủ đơn giản Điều có nghĩa là, phép toán phải cho, nguyên tắc thực đợc ngời giấy trắng bút chì khoảng thời gian hữu hạn Chẳng hạn thuật toán Euclid, ta cần thực phép chia số nguyên, phép gán phép so sánh để biết r = hay r ≠ TÝnh dõng Víi mäi liệu vào thoả mÃn điều kiện liệu vào (tức đợc lấy từ tập giá trị liệu vào), thuật toán phải dừng lại sau số hữu hạn bớc thực Chẳng hạn, thuật toán Euclid thoả mÃn điều kiện Bởi giá trị r nhỏ n (khi thùc hiƯn bíc 1), nÕu r ≠ giá trị n bớc giá trÞ cđa r ë bíc tríc, ta cã n > r = n1 > r1 = n2 > r2 DÃy số nguyên dơng giảm dần cần phải kết thúc 0, sau số bớc giá trị r phải 0, thuật toán dừng Với vấn đề đặt ra, có nhiều thuật toán giải Một vấn đề có thuật toán giải gọi vấn đề giải đợc (bằng thuật toán) Chẳng hạn, vấn đề tìm nghiệm hệ phơng trình tuyến tính vấn đề giải đợc Một vấn đề không tồn thuật toán giải gọi vấn đề không giải đợc (bằng thuật toán) Một thành tựu xuất sắc toán học kỷ 20 đà tìm vấn đề không giải đợc thuật toán Trên đà trình bày định nghĩa không hình thức thuật toán Có thể xác định khái niệm thuật toán cách xác cách sử dụng hệ hình thức Có nhiều hệ hình thức mô tả thuật toán : máy Turing, hệ thuật toán Markôp, văn phạm Chomsky dạng 0, Song vấn đề không thuộc phạm vi vấn đề mà quan tâm Đối với chúng ta, hiểu biết trực quan, không hình thức khái niệm thuật toán đủ 1.1.2 Biểu diễn thuật toán Có nhiều phơng pháp biểu diễn thuật to¸n Cã thĨ biĨu diƠn tht to¸n b»ng danh s¸ch bớc, bớc đợc diễn đạt ngôn ngữ thông thờng ký hiệu toán học Có thể biểu diễn thuật toán sơ đồ khối Tuy nhiên, nh đà nói, để đảm bảo tính xác định thuật toán, thuật toán cần đợc viết ngôn ngữ lập trình Một chơng trình biểu diễn thuật toán ngôn ngữ lập trình đà chọn Để đọc dễ dàng phần tiếp theo, độc giả cần làm quen với ngôn ngữ lập trình Pascal Đó ngôn ngữ thờng đợc chọn để trình bày thuật toán sách báo Trong sách trình bày thuật toán thủ tục hàm ngôn ngữ tựa Pascal Nói tựa Pascal, nhiều trờng hợp, ngắn gọn, không hoàn toàn tuân theo qui định Pascal Ngoài ra, có trờng hợp, xử dụng ký hiệu toán học mệnh đề ngôn ngữ tự nhiên (tiếng Anh tiếng Việt) Sau số ví dụ Ví dụ : Thuật toán kiểm tra số nguyên n(n > 2) có số nguyên tố hay không function var begin NGTO (n : integer) : boolean ; a : integer ; NGTO : = true ; a:=2; while a 1, ta gäi Mij lµ ma trËn cÊp n -1, nhận đợc từ ma trận M cách loại bỏ dòng thứ i cột thứ j, n ( det( M ) = ∑ ( −1) 1+ j a1 j det M j j =1 ) DƠ dµng thấy rằng, ta tính định thức trực tiếp dựa vào công thức đệ qui này, cần thực n! phép nhân Một số khổng lồ với n không lấy làm lớn Ngay với tốc độ máy tính lớn đại, để tính định thức ma trận cấp n = 25, cần hàng triệu năm ! Một thuật toán cổ điển khác, thuật toán Gauss - Jordan thuật toán tính định thøc cÊp n thêi gian n3 10 §Ĩ tÝnh định thức cấp n = 100 thuật toán máy tính lớn ta cần đến giây Ví dụ : Bài toán tháp Hà Nội Trong vÝ dơ 2, mơc 1.1 ta ®· ®a mét thuật toán để chuyển n đĩa từ cọc A sang cäc B Ta thư tÝnh xem, cÇn thùc hiƯn lần chuyển đĩa từ cọc sang cọc khác (không đặt đĩa to lên đĩa nhỏ) để chuyển ®ỵc n ®Üa tõ cäc A sang cäc B Gäi số F(n) Từ thuật toán, ta có : F(1) = 1, F(n) = 2F(n-1) + víi n > víi n = 1, 2, ta cã F(1) = 1, F(2) = 3, F(3) = B»ng cách qui nạp, ta chứng minh đợc F(n) = 2n - Víi n = 64, ta cã F(64) = 264 -1 lần chuyển Giả sử lần chuyển đĩa từ cọc sang cọc khác, cần giây Khi để thực 264 -1 lần chuyển, ta cần x 1011 năm Nếu tuổi vũ trụ 10 tỉ năm, ta cần 50 lần tuổi vũ trụ để chuyển 64 đĩa ! Đối với vấn đề có nhiều thuật toán, số thuật toán hiệu (chạy nhanh hơn) thuật toán Tuy nhiên, có vấn đề không tồn thuật toán hiệu quả, tức có thuật toán, song thời gian thực lớn, thực tế thực đợc, dù máy tính lớn đại 1.2.3 Đánh giá thời gian thực thuật toán nh ? Có hai cách tiếp cận để ®¸nh gi¸ thêi gian thùc hiƯn cđa mét tht to¸n.Trong phơng pháp thử nghiệm, viết chơng trình cho chạy chơng trình với liệu vào khác máy tính Thời gian chạy chơng trình phụ thuộc vào nhân tố sau : Các liệu vào Chơng trình dịch để chuyển chơng trình nguồn thành mà máy Tốc độ thực phép toán máy tính đợc sử dụng để chạy chơng trình Vì thời gian chạy chơng trình phụ thuộc vào nhiều nhân tố, nên ta biểu diễn xác thời gian chạy đơn vị thời gian chuẩn, chẳng hạn giây Trong phơng pháp lý thuyết (đó phơng pháp đợc sử dụng sách này), ta sÏ coi thêi gian thùc hiƯn tht to¸n nh hàm số cỡ liệu vào Cỡ liệu vào tham số đặc trng cho liệu vào, có ảnh hởng định đến thời gian thực chơng trình Cái mà chọn làm cỡ liệu vào phụ thuộc vào thuật toán cụ thể Đối với thuật toán 11 xếp mảng, cỡ liệu số thành phần mảng Đối với thuật toán giải hệ n phơng trình tuyến tính với n ẩn, ta chọn n cỡ Thông thờng cỡ liệu vào số nguyên dơng n Ta sử dụng hàm số T(n), n cỡ liệu vào, để biểu diễn thời gian thực tht to¸n Thêi gian thùc hiƯn tht to¸n T(n) nãi chung không phụ thuộc vào cỡ liệu vào, mà phụ thuộc vào liệu vào cá biệt Chẳng hạn, ta xét toán xác định đối tợng a có mặt danh sách n phần tử (a1, a2, an) hay không Thuật toán là, so sánh a với phần tử danh sách từ đầu đến cuối danh sách, gặp phần tử = a dừng lại, đến hết danh sách mà không gặp a, trờng hợp a danh sách Các liệu vào a danh sách (a1, a2, , an) (có thể biểu diễn danh sách mảng, chẳng hạn) Cỡ liệu vào n Nếu a1 = a cần phép so sánh Nếu a1a, a2 = a, cần phép so sánh Còn a, i = 1, , n-1 an = a, a danh sách, ta cần n phép so sánh Nếu xem thời gian thực T(n) sè phÐp to¸n so s¸nh, ta cã T(n) , = phép toán sơ cấp Phép toán so sánh hai xâu ký tự xem phép toán sơ cấp, thời gian thực phụ thuộc vào độ dài xâu 1.2.4 Ký hiệu ô lớn đánh giá thời gian thực thuật toán ký hiệu ô lớn Khi đánh giá thời gian thực phơng pháp toán học, bỏ qua nhân tố phụ thuộc vào cách cài đặt tập trung vào xác định độ lớn thời gian thực T(n) Ký hiệu toán học ô lớn đợc sử dụng để mô tả độ lớn hàm T(n) Giả sử n số nguyên không âm, T(n) f(n) hàm thực không âm Ta viết T(n) = 0(f(n)) (đọc : T(n) ô lớn f(n)), tồn số dơng c no cho T(n) c f(n), víi mäi n ≥ no NÕu mét tht to¸n cã thêi gian thùc hiƯn T(n) = 0(f(n)), chóng ta sÏ nãi r»ng tht to¸n cã thêi gian thùc hiƯn cấp f(n) Từ định nghĩa ký hiệu ô lớn, ta xem hàm f(n) cận T(n) 12 VÝ dơ : Gi¶ sư T(n) = 3n2 + 5n + Ta cã 3n2 + 5n + begin m:=n; n:=r; r : = m mod n ; 17 end ; Euclid : = n ; (6) end ; Thêi gian thực thuật toán phụ thuộc vào số nhỏ hai số m n Giả sử n n > 0, cỡ liệu vào n Các lệnh (1) (6) có thời gian thực 0(1) Vì thời gian thực thuật toán thời gian thực lệnh while ta đánh giá thời gian thực lệnh while (2) Thân lệnh này, khối gồm ba lệnh (3), (4) (5) Mỗi lệnh có thời gian thực 0(1), khối có thời gian thực 0(1) Còn phải đánh giá số lớn lần thực lặp khối Ta có : m = n.q1 + r1 , ≤ r1 < n n = r1q2 + r2 , ≤ r2 < r1 NÕu r1 ≤ n/2 th× r2 < r1 ≤ n/2, r2 < n/2 Nếu r1 > n/2 q2 = 1, tøc lµ n = r1 + r2 , r2 < n/2 Tóm lại, ta cã r2 < n/2 Nh vËy, cø hai lÇn thùc khối phần d r giảm nửa n Gọi k số nguyên lớn cho 2k n Số lần lặp khối tối đa 2k+12log2n+1 Do thời gian thực lệnh while 0(log2n) Đó thời gian thực thuật toán Ví dụ DÃy số Fibonacci đợc xác định cách đệ qui nh sau : fo = ; f1 = ; fn = fn-1 + fn-2 với n Các thành phần d·y lµ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, DÃy có nhiều áp dụng toán học, tin học lý thuyết trò chơi Thuật toán đệ qui : function Fibo1 (n : integer) : integer ; begin if n