SLIDE MÔN TOÁN RỜI RẠC GIÚP CÁC BẠN SINH VIÊN DỄ DÀNG HỌC TẬP TRONG MMON HỌC NÀY, SLIDE NÀY CHỈ GỒM CHƯƠNG 1 MÌNH SẼ UPDATE TIẾP MONG CÁC BẠN THEO DỖI :BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Trang 1TOÁN RỜI RẠC CHO CNTT
(D ISCRETE M ATHEMATICS FOR I NFORMATION T ECHNOLOGY )
GV: Đặng Hữu Nghị Sđt: 0989640319
Email: nghidanghuu@gmail.com
Trang 2TÀI LIỆU THAM KHẢO
1. Nguyễn Đức Nghĩa, Nguyễn Tô Thành Toán rời
rạc NXB Đại học QG Hà Nội 2006
2. Đỗ Đức Giáo Toán rời rạc ứng dụng trong tin
học NXB Giáo dục 2008.
3. Kenneth H Rosen (Phạm Văn Thiều, Đặng Hữu
Thịnh dịch) Toán rời rạc ứng dụng trong tin
học NXB Khoa học và Kỹ thuật Hà Nội 2003
4. Thực hành bằng Ngôn ngữ lập trình C sử dụng
trình biên dịch:
Turbo C++ 4.0
Trang 3CHƯƠNG 1: THUẬT TOÁN
1.1 Khái niệm về thuật toán
1.2 Các đặc trưng của thuật toán
1.3 Ngôn ngữ thuật toán
1.4 Độ phức tạp của thuật toán
1.5 Đệ quy
3
Trang 41.1 KHÁI NIỆM VỀ THUẬT TOÁN
Quá trình giải quyết một bài toán trên máy tính
có thể biểu diễn theo một sơ đồ chung sau:
Trang 51.1 KHÁI NIỆM VỀ THUẬT TOÁN
Thuật toán là một trong những khái niệm cơ sở của tin
học Khái niệm thuật toán được hiểu theo nghĩa trực giác
như sau:
Thuật toán là một hệ thống chặt chẽ và rõ ràng các quy
tắc nhằm xác định một dãy các thao tác trên những đối
tượng, sao cho sau một số hữu hạn bước thực hiện các
thao tác ta đạt được mục tiêu định trước.
5
Trang 61.1 KHÁI NIỆM VỀ THUẬT TOÁN
Ví dụ: Thuật toán tìm ước số chung lớn nhất (ƯCLN) của
hai số nguyên dương a và b như sau:
Bước 1: Nhập số liệu a và b, thực hiện bước (2)
Bước 2: Nếu a = b thì thông báo kết quả ƯCLN là a,
dừng thuật toán Nếu a b thì thực hiện bước (3)
Bước 3: Nếu a > b thì gán a = a - b, nếu a < b thì gán b =
b - a, thực hiện bước (2)
Trang 71.2 CÁC ĐẶC TRƯNG CỦA THUẬT TOÁN
Tính phổ dụng: thuật toán không đề cập chỉ một bài toán
riêng lẻ, mà phải bao hàm một lớp bài toán cùng một
kiểu
Tính hữu hạn: hay còn gọi là tính kết thúc (tính dừng),
thuật toán bao giờ cũng phải dừng sau một số hữu hạn
bước thực hiện
Tính nhất quán: hay còn gọi là tính xác định của thuật
toán Đặc trưng này thể hiện ở mỗi bước các thao tác
phải hết sức rõ ràng, không thể gây nên sự nhập nhằng,
lẫn lộn, tuỳ tiện Nói cách khác, trong cùng một điều
kiện, hai bộ xử lý (người hoặc máy) thực hiện cùng một
bước của thuật toán thì phải cho cùng một kết quả 7
Trang 81.2 CÁC ĐẶC TRƯNG CỦA THUẬT TOÁN
Đại lượng vào: Một thuật toán có thể có nhiều
đại lượng vào mà chúng ta thường gọi là dữ liệu
vào
Đại lượng ra: Sau khi dừng thuật toán, tuỳ theo
chức năng mà thuật toán đảm nhiệm chúng ta có
thể thu được một số đại lượng ra xác định
Trang 91.2 CÁC ĐẶC TRƯNG CỦA THUẬT TOÁN
Tính hiệu quả:
Yêu cầu đầu tiên của tính hiệu quả của thuật toán là
sự đúng đắn, cụ thể là với dữ liệu vào cho trước, thuật
toán hoạt động sau một số hữu hạn bước sẽ dừng và
cho kết quả mong muốn.
Yêu cầu thứ hai của tính hiệu quả là tính hữu hiệu:
Trong số các thuật toán thực hiện cùng một chức
năng, hãy chọn những thuật toán tốt nhất Tiêu
chuẩn tốt ở đây được hiểu là:
Thuật toán thực hiện nhanh, tốn ít thời gian
Thuật toán dùng ít chỗ để lưu trữ các kết quả trung gian
9
Trang 101.3 NGÔN NGỮ THUẬT TOÁN
Có thể biểu diễn thuật toán bằng 3 cách sau:
Bằng lời.
Bằng giả mã.
Bằng sơ đồ khối.
Ở đây chúng ta chỉ xem xét việc biểu diễn thuật
toán bằng sơ đồ khối, ưu điểm nổi bật của nó là
tính trực quan
Trang 111.3 NGÔN NGỮ THUẬT TOÁN
2 Khối mở đầu hoặc kết
Thúc
Dùng mở đầu hoặc kết thúc chương trình
quả
toán và thay đổi giá trị của các biến
chương trình
trình con
11
Trang 121.3 NGÔN NGỮ THUẬT TOÁN
Cấu trúc tuần tự: Thực hiện lần lượt <lệnh 1>,
<lệnh 2>, <lệnh 3> …
Trang 131.3 NGÔN NGỮ THUẬT TOÁN
Cấu trúc phân nhánh / điều kiện:
13
Trang 141.3 NGÔN NGỮ THUẬT TOÁN
Cấu trúc tuyển
Biểu thức
Trang 151.3 NGÔN NGỮ THUẬT TOÁN
Cấu trúc chu trình / lặp
Lặp theo tham biến
15
Trang 161.3 NGÔN NGỮ THUẬT TOÁN
Lặp theo điều kiện
Trang 171.3 NGÔN NGỮ THUẬT TOÁN
Đ
S
Đ S
17
Trang 181.3 NGÔN NGỮ THUẬT TOÁN
Ví dụ: Xây dựng sơ đồ
khối (thuật toán) tính
tổng của một dãy số
thực a1, a2,…,an
Trang 191.3 NGÔN NGỮ THUẬT TOÁN
Ví dụ: Biểu diễn thuật toán tìm số lớn nhất trong
một dãy hữu hạn các số nguyên theo dạng giả mã:
Dữ liệu vào (input): a[1 n], a là mảng các số nguyên,
n>0 là số các số trong mảng a;
Dữ liệu ra (output): max, số lớn nhất trong mảng a;
int TimMax(a: mảng các số nguyên) {
Trang 201.3 NGÔN NGỮ THUẬT TOÁN (BÀI TẬP)
B1: Vẽ sơ đồ khối thuật toán tìm ƯSCLN của 2 số
Trang 211.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Tính hiệu quả của thuật toán
Khi giải một bài toán, chúng ta cần chọn trong số các thuật
toán một thuật toán mà chúng ta cho là “tốt” nhất.
dựa trên cơ sơ nào để đánh giá thuật toán này “tốt” hơn thuật
toán kia?
Thông thường ta dựa trên hai tiêu chuẩn sau:
Thuật toán đơn giản, dễ hiểu, dễ cài đặt (dễ viết chương trình).
Thuật toán hiệu quả: Chúng ta thường đặc biệt quan tâm đến thời
gian thực hiện của thuật toán (gọi là độ phức tạp tính toán), bên cạnh
đó chung ta cũng quan tam tới dung lượng không gian nhớ cần thiết
để lưu giữ các dữ liệu vào, ra và các kết quả trung gian trong quá trình tính toán.
21
Trang 221.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Tại sao cần có thuật toán có tính hiệu quả
Xét ví dụ 1: kiểm tra tính nguyên tố của một số nguyên
Trang 231.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Dễ dàng nhận thấy rằng, nếu n là một số nguyên
tố chúng ta phải mất n-2 phép chia lấy phần dư
(%)
Giả sử một siêu máy tính có thể tính được 1 trăm
nghìn tỉ phép tính % trong 1 giây (1014)như vậy
để kiểm tra 1 số có 25 chữ số mất khoảng
Trang 241.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
int nguyento (int n)
Trang 251.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Ví dụ: Bài toán tháp Hà Nội
Có 3 cọc A, B, C Lúc đầu, ở cọc A có n đĩa được lồng
theo thứ tự nhỏ trên lớn dưới Yêu cầu chuyển n đĩa từ
cọc A sang cọc B với điều kiện:
Mỗi lần chỉ được chuyển một đĩa
Không có tình huống đĩa to ở trên đĩa nhỏ (dù là tạm
thời)
Được phép sử dụng cọc C làm trung gian.
Trang 261.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Trường hợp một đĩa:
Chuyển đĩa từ cọc A sang cọc B.
Trường hợp 2 đĩa:
Chuyển đĩa thứ nhất từ cọc A sang cọc C;
Chuyển đĩa thứ hai từ cọc A sang cọc B;
Chuyển đĩa thứ nhất từ cọc C sang cọc B.
Trang 271.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Trang 281.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Ta thấy với trường hợp n đĩa (n>2) nếu ta xem (n-1) đĩa
ở trên đóng vai trò như đĩa thứ nhất thì có thể xử lý như
trường hợp hai đĩa, nghĩa là:
Chuyển (n-1) đĩa trên từ A sang C
Chuyển đĩa thứ n từ A sang B
Chuyển (n-1) đĩa từ C sang B.
Trang 291.4 ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Nếu gọi F(n) là số lần chuyển đĩa.
Người ta chứng minh được F(n) = 2 n – 1
Với n = 64, ta có F(64) = 2 64 –1 lần chuyển Giả sử mỗi lần chuyển 1 đĩa từ cọc này sang cọc kia, cần 1 giây Khi đó để thực hiện 2 64 –1 lần chuyển cần 5.10 11 năm Nếu tuổi của
vũ trụ là 10 tỉ năm , ta cần 50 lần tuổi của vũ trụ để chuyển
64 đĩa!
Qua thí dụ trên ta thấy, tuy bài toán tháp Hà Nội tồn tại thuật toán giải nhưng với n đủ lớn thì thuật toán không khả thi
29
Trang 301.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Có hai cách tiếp cận để đánh giá thời gian thực hiện của
một thuật toán:
Trang 311.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Giả sử n là số nguyên không âm f(n) và g(n) là
các hàm thực không âm Ta viết f(n) = O(g(n))
(đọc f(n) là ô lớn của g(n)), nếu và chỉ nếu tồn tại
các hằng số dương c và n 0 sao cho f(n) <= c.g(n),
với mọi n>= n 0 .
Ví dụ Giả sử f(n) = 3n2 + 4n +5.
Ta có : 3n 2 + 4n + 5 <= 3n 2 + 4n 2 + 5n 2 = 12n 2 ,
với mọi n >= 1.
Vậy f(n) = O(n 2 ) thuật toán có thời gian thực
hiện cấp n 2 , hoặc thuật toán có thời gian thực
hiện bình phương.
31
Trang 321.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Ví dụ: Giả sử f(n) = 2n + 23
Ta có f(n) < 2x2 n với mọi x > 5
Vì vậy f(n) = O(2 n ).
Trang 331.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Trang 341.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
tính
n log n Bình
phương
Lập phương
Trang 351.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
35
Trang 361.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Xét ví dụ: Giả sử một bài toán nào đó, có hai thuật toán giải là A và B.
Thuật toán A có thời gian thực hiện là f A (n) = O(n 2 )
Thuật toán B có thời gian thực hiện là f B = O(n.logn).
Với n = 1024 thuật toán A cần 1048576 phép toán sơ cấp, thuật toán B đòi hỏi 10240 phép toán sơ cấp.
Nếu cần một micro-giây cho một phép toán sơ cấp thì thuật toán A cần khoảng 1,05 giây trong khi đó thuật toán B cần khoảng 0,01 giây.
Nếu n = 2048 , thì thuật toán A đòi hỏi khoảng 4,2 giây, trong khi thuật toán B chỉ đòi hỏi khoảng 0,02 giây.
Vì vậy nếu một thuật toán có thời gian thực hiện O(n 2 ) mà ta tìm ra được một thuật toán khác cho bài toán đó với thời gian
Trang 371.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Các quy tắc đánh giá độ phức tạp về thời gian
thực hiện thuật toán
f1(n) + f2(n) = O(max (g1(n), g2(n))) 37
Trang 381.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Quy tắc nhân :
Nếu tương ứng với P1 và P2 là
f1(n) = O(g1(n)),
f2(n) = O(g2(n)) thì thời gian thực hiện P1 và P2 lồng nhau sẽ là :
f1(n).f2(n) = O(g1(n).g2(n))
Trang 391.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Ví dụ:
Câu lệnh gán : x = x +1 có thời gian thực hiện bằng c
(hằng số) nên được đánh giá là O(1).
Câu lệnh for (i = 1; i<= n; i++) x = x +1 có thời gian
thực hiện O(n.1) = O(n).
Câu lệnh for (i= 1; i<=n; i ++)
for (j = 1; j<=n; j++) x = x +1
Cũng có thể thấy O(c.g(n)) = O(g(n)) chẳng hạn
Trang 401.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
log (n!) = O(nlogn) nlog (n!) = O(n2logn)
(3n2 + 2n) = O(n2) (3n2 + 2n)logn = O(n2logn)
Vậy f(n) = O(n2logn)
Trang 411.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Trang 421.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Các quy tắc đánh giá độ phức tạp về thời gian thực hiện thuật toán
1 Thời gian thực hiện các câu lệnh đơn
2 Thời gian thực hiện câu lệnh điều kiện
3 Thời gian thực hiện lệnh Case
4 Thời gian thực hiện câu lệnh for
5 Thời gian thực hiện câu lệnh While
6 Thời gian thực hiện câu lệnh Do while
Trang 431.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Thời gian thực hiện các câu lệnh đơn
Lệnh đơn gồm: Phép gán, các câu lệnh đọc, viết, câu lệnhgoto
Thời gian thực hiện lệnh đơn: O(1) tức là thời gian thực hiệnkhông đổi
43
Trang 441.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Thí dụ: xét đoạn chương trình sau:
(1) for (i = 1; i<= n-1; i++) {
Trang 451.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT
Đánh giá thời gian thực hiện các lệnh if:
Giả sử thời gian thực hiện các lệnh S1, S2, là O(f1(n)) và O(f2(n)) tương ứng.
Khi đó thời gian thực hiện lệnh if là: O(max(f1(n),f2(n))).
Trang 461.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT
Trang 471.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Thời gian thực hiện câu lệnh for
for (i= m ; i<= n; i++) S Với m, n nguyên và m <= n.
Đánh giá thân vòng for:
lệnh gán,
lệnh tăng chỉ số lặp,
lệnh kiểm tra điều kiện dừng,
đều là lệnh đơn nên thường có cận là O(1) = c
Gọi f(n) là số lần thực hiện lệnh S Khi đó thời gian thực
Trang 481.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Thời gian thực hiện câu lệnh While
Câu lệnh:
While (B) S
B: điều kiện
S: lệnh.
Thời gian thực hiện lệnh while được đánh giá:
Giả sử thời gian thực hiện lệnh S (thân của lệnh
Trang 491.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Thí dụ: xét đoạn chương trình:
(1) i = 1;
(2) while (x <> A[i])
Hai câu lệnh gán (1), (3) đều là O(1)
Vòng lặp while ở hai dòng (2) và (3) có mục đích đi tìm vị
trí của phần tử có giá trị bằng x trên mảng A (giả thiết x
có mặt trên mảng) Như vậy tối đa số lần lặp là n (với n
là số phần tử của mảng A).
Từ đó suy ra thời gian thực hiện của đoạn chương trình
trên là O(n).
49
Trang 501.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Thời gian thực hiện câu lệnh do while
do {
S1, S2, , Sn}
while(B);
B: điều kiện
Si (i = 1, 2,… , n) các câu lệnh.
Giả sử thời gian thực hiện khối {S1, S2,…Sn} là O(f(n))
Giả sử g(n) là số tối đa các lần lặp
Khi đó thời gian thực hiện lệnh do while là O(f(n).g(n)).
Trang 511.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Ví dụ phân tích thời gian hoạt động của đoạn chương trình sau:
Thời gian thực hiện chương trình phụ thuộc vào n.
Câu lệnh {1}, {3} và {6} có thời gian thực hiện O(1)
Câu lệnh lặp for {2} có số lần lặp 2n như vậy thời gian thực hiện là O(n)
Câu lệnh {5} có số lần lặp là n, như vậy lệnh {5} có thời gian thực hiện là O(n) Lệnh lặp for {4} có số lần lặp là n, như vậy lệnh {4} có thời gian thực hiện là O(n 2 )
Vậy thời gian thực hiện đoạn chương trình trên là:
Max(O(1), O(n), O(n 2 )) = O(n 2 )
Trang 521.5 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Ví dụ phân tích thời gian hoạt động của đoạn chương trình
sau:
Lệnh {3} có thời gian thực hiện O(1)
Khi i = 1, j chạy từ 1 đến 1 Lệnh for {2} lặp 1 lần
Khi i = 2, j chạy từ 1 đến 2 Lệnh for {2} lặp 2 lần
Khi i = n, j chạy từ 1 đến n Lệnh for {2} lặp n lần
Như vậy lệnh {3} được lặp 1 + 2 + ⋯ + 𝑛 = 𝑛 𝑛+1
2 do đó lệnh {1} có thời gian thực hiện O(n 2 )
{1} for (i=1; i <= n; i++)
Trang 561.6 ĐỆ QUY
Đệ quy tuyến tính
Hàm đệ quy tuyến tính là hàm mà trong thân hàm có
duy nhất một lời gọi hàm gọi lại chính nó một cách
tường minh
Thuật toán đệ quy tuyến tính:
Trang 571.6 ĐỆ QUY
<kiểu dữ liệu hàm> <tên hàm> (<danh sách tham số>){
if (<điều kiện dừng>){
// Trả về giá trị hay kết thúc công việc}
// Thực hiện một số công việc (nếu có)
<tên hàm> (<danh sách tham số>) ; // Thực hiện một số công việc (nếu có)
Trang 58Dựa vào công thức trên ta có thể xây dựng hàm để tính n! một
cách đệ quy như sau:
long giaithua ( int n)
{
if ( n == 0 || n == 1) return 1;
else return ( n * giaithua ( n - 1 ) ) ;
Trang 591.6 ĐỆ QUY
Đệ quy nhị phân
Hàm đệ quy nhị phân là hàm mà trong thân của nó có
hai lời gọi hàm gọi lại chính nó một cách tường minh
Thuật toán đệ quy nhị phân:
59
Trang 60// Thực hiện một số công việc (nếu cú)
<tên hàm> (<danh sách tham số>) ; //Giải quyết vấn đề nhỏ hơn // Thực hiện một số công việc (nếu có)
<tên hàm> (<danh sách tham số>); // Giải quyết vấn đề còn lại // Thực hiện một số công việc nếu có
Trang 621.6 ĐỆ QUY
Trang 631.6 ĐỆ QUY
#include <stdio.h>
#include <conio.h>
// ham de quy tinh so Fibonaci thu n
long fibonaci (long n)
Trang 641.6 ĐỆ QUY
Đệ quy phi tuyến
Hàm đệ quy phi tuyến là hàm mà trong thân của hàm
có lời gọi hàm gọi lại chính nó được đặt bên trong
vòng lặp
Thuật toán đệ quy phi tuyến:
Trang 651.6 ĐỆ QUY
<kiểu dữ liệu hàm> <tên hàm> (<danh sách tham số>)
{
for(int i = 1; i <= n; i++) { // Thực hiện một số công việc (nếu có)
if (<điều kiện dừng>) { …
// Trả về giá trị hay kết thúc công việc }
else { // Thực hiện một số công việc (nếu có)
<tên hàm> (<danh sách tham số>) ; // Thực hiện một số công việc (nếu có) }
} }
65
Trang 661.6 ĐỆ QUY
Ví dụ:
Tính số hạng thứ n của dãy số x1, x2, …, xn được định
nghĩa như sau:
X0 = 1;
Xn = n2X0 + (n-1)2X1 + + 12Xn-1, n ≥ 1
Trang 681.6 ĐỆ QUY
Đệ quy hỗ tương
Hàm đệ quy hỗ tương là hàm mà trong thân của hàm
này có lời gọi hàm đến hàm kia và trong thân của hàm
kia lại có lời gọi hàm tới hàm này.
Thuật toán đệ quy hỗ tương như sau:
Trang 691.6 ĐỆ QUY
<kiểu dữ liệu hàm> <tên hàm 1> (<danh sách tham số>)
{
// Thực hiện một số công việc (nếu có)
<tên hàm 2> (<danh sách tham số>) ;
// Thực hiện một số công việc (nếu có) }
<kiểu dữ liệu hàm> <tên hàm 2> (<danh sách tham số>)
{
// Thực hiện một số công việc (nếu có)
<tên hàm 1> (<danh sách tham số>) ;
// Thực hiện một số công việc (nếu có)
Trang 701.6 ĐỆ QUY
Ví dụ: Tính số hạng thứ n của hai dãy {Xn}, {Yn} được
định nghĩa như sau:
Trang 721.6 ĐỆ QUY (BÀI TẬP)
Bài 1: Xây dựng hàm để tính S = 1 + 2 + 3 + … + n
theo phương pháp đệ quy
Công thức tổng quát cho bài này là:
S(0) = 0
S(n) = S(n-1) + n