You are on page 1of 44

Cấu trúc dữ liệu & Giải thuật

Trầm Vũ Kiệt
Đánh giá độ phức tạp
thuật toán
Chương 1 (tiếp theo)
Nội dung
• Giới thiệu
• Phân tích trực tiếp các đoạn mã
• Phân tích đoạn mã có lời gọi chương trình con
• Đánh giá dựa trên thực nghiệm
• Bài tập

05/08/2023 Cấu trúc dữ liệu & Giải thuật 3


Nội dung
• Giới thiệu
• Phân tích trực tiếp các đoạn mã
• Phân tích đoạn mã có lời gọi chương trình con
• Đánh giá dựa trên thực nghiệm
• Bài tập

05/08/2023 Cấu trúc dữ liệu & Giải thuật 4


Giới thiệu
• Trước khi thực hiện tính độ phức tạp của thuật toán A
giải bài toán P, ta cần hàm f(n)
• Xác định độ dài dữ liệu n: có thể là số ký tự, số phần tử của
mảng,…
• Tiêu chí đánh giá: thống nhất là số các thao tác cơ bản (gán,
so sánh, …)
• Để đánh giá có thể sử dụng:
• Phân tích trực tiếp để tính số các thao tác
• Phương pháp đệ quy

05/08/2023 Cấu trúc dữ liệu & Giải thuật 5


Giới thiệu
• Dựa trên một số quy tắc:
• Quy tắc cộng
• Quy tắc nhân
• Quy tắc phân tích một số câu lệnh
• Xét tính chất của chương trình con

05/08/2023 Cấu trúc dữ liệu & Giải thuật 6


Quy tắc cộng
• Gọi:
• T(n) là thời gian thực hiện của chương trình
• T1(n) và T2(n) là thời gian thực hiện của 2 đoạn chương trình
con nối tiếp nhau (độc lập) P1 và P2
• T1(n) = O(f1(n)) và T2(n) = O(f2(n))
• Khi đó thời gian (độ phức tạp thời gian) thực hiện của 2 đoạn
chương trình đó là: T(n) = T1(n) + T2(n) = O(max{f1(n),f2(n)}
• Chứng minh:
• Theo đầu bài, tồn tại các hằng M1, M2, n1, n2 để:

• Khi đó:
05/08/2023 Cấu trúc dữ liệu & Giải thuật 7
Ví dụ Quy tắc cộng
• Ví dụ : Trong một chương trình có 3 bước thực
hiện mà thời gian thực hiện từng bước lần lượt là
O(n2), O(n3) và O(nlog2n) thì thời gian thực hiện 2
bước đầu là O(max(n2, n3)) = O(n3).
• Thời gian thực hiện chương trình sẽ là
O(max(n3, nlog2n)) = O(n3)

05/08/2023 Cấu trúc dữ liệu & Giải thuật 8


Ví dụ Quy tắc cộng
• Chú ý : Nếu g(n) ≤ f(n) với mọi n ≥ n0 thì O(f(n)
+g(n)) cũng là O(f(n)).

• VD : O(n4 + n2) = O(n4);


O(n + log2n) = O(n).

05/08/2023 Cấu trúc dữ liệu & Giải thuật 9


Quy tắc nhân
• T1(n) và T2(n) là thời gian thực hiện của 2 đoạn
chương trình con lồng nhau (phụ thuộc) P1, P2 và
• T1(n)=O(f1(n)); T2(n)=O(f2(n))
• Khi đó thời gian (độ phức tạp thời gian) thực hiện
của 2 đoạn chương trình đó là
T(n) = T1(n) * T2(n) = O(f1(n) * f2(n))
• Chứng minh: tương tự với quy tắc cộng
05/08/2023 Cấu trúc dữ liệu & Giải thuật 10
Quy tắc phân tích câu lệnh
• Các câu lệnh đơn (gán, đọc, ghi, …) có độ phức tạp là
hằng số - O(1)
• Ví dụ:
(1) read(a)
(2) read(b)
(3) read(c)
(4) delta = b*b - 4*a*c
• Nhận xét: trong đoạn chương trình chỉ bao gồm các
lệnh đơn kế tiếp nhau (không chứa các vòng lặp), theo
quy tắc cộng => độ phức tạp thuật toán là hằng O(1)
05/08/2023 Cấu trúc dữ liệu & Giải thuật 11
Quy tắc phân tích câu lệnh
• Cấu trúc if: thời gian kiểm tra điều kiện + thời gian
thực hiện sau THEN hoặc ELSE
• Cấu trúc lặp:
• Thời gian thực hiện vòng lặp là tổng thời gian thực hiện
của thân vòng lặp.
• Nếu số bước tính trong vòng lặp không đổi (theo mỗi
bước lặp) thì thời gian thực hiện vòng lặp bằng tích của
số lần lặp nhân với thời gian thực hiện thân vòng lặp.

05/08/2023 Cấu trúc dữ liệu & Giải thuật 12


Nội dung
• Giới thiệu
• Phân tích trực tiếp các đoạn mã
• Phân tích đoạn mã có lời gọi chương trình con
• Đánh giá dựa trên thực nghiệm
• Bài tập

05/08/2023 Cấu trúc dữ liệu & Giải thuật 13


Phân tích trực tiếp
• Phương pháp chung:
• Phân tích trực tiếp đoạn mã và sử dụng các kỹ thuật:
• Phép đếm
• Tính tổng hữu hạn
Xác định số phép toán chủ yếu
• Xét dấu hàm
•…
• Phép toán chủ yếu trong các đoạn mã là phép gán và
so sánh
• Phương pháp này không giải quyết được tất cả các
trường hợp
05/08/2023 Cấu trúc dữ liệu & Giải thuật 14
1: s = 0;
Phân tích trực tiếp 2: i = 1;
• Ví dụ 1: Khảo sát độ 3: while (i <= n) {
phức tạp trên số phép 4: j = n - 1;
gán và so sánh trong 5: while (j >= 1) {
thuật toán? 6: s = s + 1;
7: j = j - 1;
8: }
9: i = i + 1;
05/08/2023
10:
Cấu trúc dữ liệu & Giải thuật
} 15
1: s = 0; 1: phép gán
2: i = 1; 2: phép gán
3: while (i <= n) { 3: phép so sánh
4: j = n - 1; 4: phép gán
5: while (j >= 1) { 5: phép so sánh
6: s = s + 1; 6: phép gán
7: j = j - 1; 7: phép gán
8: } 8:
9: i = i + 1; 9: phép gán
10:
05/08/2023
} 10:
Cấu trúc dữ liệu & Giải thuật 16
Phân tích trực tiếp
Số phép gán =
=
=

05/08/2023 Cấu trúc dữ liệu & Giải thuật 17


1: sum = 0;
Phân tích trực tiếp 2: i = 1;
• Ví dụ 2: Khảo sát độ 3: while (i <= n) {
phức tạp trên số phép 4: j = n – i*i;
gán và so sánh trong 5: while (j <= i*i) {
thuật toán? 6: sum += i*j;
Pi
7: j = j + 1;
8: }
9: i = i + 1;
05/08/2023
10:
Cấu trúc dữ liệu & Giải thuật
} 18
Phân tích trực tiếp
Số phép gán =
=
=

05/08/2023 Cấu trúc dữ liệu & Giải thuật 19


Nội dung
• Giới thiệu
• Phân tích trực tiếp các đoạn mã
• Phân tích đoạn mã có lời gọi chương trình con
• Đánh giá dựa trên thực nghiệm
• Bài tập

05/08/2023 Cấu trúc dữ liệu & Giải thuật 20


Phân tích đoạn mã có lời gọi chương
trình con
• Gọi chương trình con không đệ quy

05/08/2023 Cấu trúc dữ liệu & Giải thuật 21


Phân tích đoạn mã có lời gọi chương
trình con
• Gọi chương trình con đệ quy

• Tính thời gian thực hiện của A?


05/08/2023 Cấu trúc dữ liệu & Giải thuật 22
Độ phức tạp chương trình con dạng đệ
quy
• Cách giải quyết:
1. Thành lập phương trình đệ quy
2. Giải phương trình đệ quy
• Nghiệm của lời giải ở bước 2 là thời gian thực
hiện chương trình

05/08/2023 Cấu trúc dữ liệu & Giải thuật 23


Độ phức tạp chương trình con dạng đệ
quy
• Phương trình đệ quy: Biểu diễn mỗi liên hệ giữa
T(n) với T(k), k<n.
• Trong đó T(n) thời gian thực hiện chương trình và
T(k) thời gian thực hiện với kích thước bộ dữ liệu
là k, và k<n.
• Để lập phương trình: Căn cứ vào chương trình đệ
quy.

05/08/2023 Cấu trúc dữ liệu & Giải thuật 24


Độ phức tạp chương trình con dạng đệ
quy

05/08/2023 Cấu trúc dữ liệu & Giải thuật 25


Độ phức tạp chương trình con dạng đệ
quy
• Ví dụ: xét hàm tính giai thừa
Function gt(n)
begin
if n=0 then gt=1
else gt=n*gt(n-1)
end
• Gọi T(n) là thời gian tính n!, thì T(n-1) là thời gian
tính (n-1)!
• Khi n=0, ta có C(0)=1 (phép gán)
05/08/2023 Cấu trúc dữ liệu & Giải thuật 26
Độ phức tạp chương trình con dạng đệ
quy
• Ví dụ: xét hàm tính giai thừa
Function gt(n)
begin
if n=0 then gt=1
else gt=n*gt(n-1)
end
• Khi n>0, hàm gọi đệ quy gt(n-1), tốn T(n-1)
• Tổng hợp kết quả ở đây cần 1 phép gán, d*=1
05/08/2023 Cấu trúc dữ liệu & Giải thuật 27
Độ phức tạp chương trình con dạng đệ
quy
• Ví dụ: xét hàm tính giai thừa
Function gt(n)
begin
if n=0 then gt=1
else gt=n*gt(n-1)
end
• Khi n>0, hàm gọi đệ quy gt(n-1), tốn T(n-1)
• Tổng hợp kết quả ở đây cần 1 phép gán, d*=1
05/08/2023 Cấu trúc dữ liệu & Giải thuật 28
Độ phức tạp chương trình con dạng đệ
quy
• Giải phương trình đệ quy – Phương pháp truy hồi
1. Với n>k>n0: dùng phương trình đệ quy lần lượt
thay thế T(k) vào vế phải
2. Dừng khi k=n0
3. Thế T(n0) để tìm T(n)

05/08/2023 Cấu trúc dữ liệu & Giải thuật 29


Độ phức tạp chương trình con dạng đệ
quy
• Giải phương trình đệ quy – Phương pháp truy hồi
1. Ví dụ: Giải

T(n) = T(n-1) + 1
= T(n-2) + 1 + 1
….
= T(n-i) + i
Dừng khi n-i = 0, hay i=n, khi đó T(n) = 1 + n = O(n)
05/08/2023 Cấu trúc dữ liệu & Giải thuật 30
Độ phức tạp chương trình con dạng đệ
quy
• Giải phương trình đệ quy – Phương pháp truy hồi
1. Ví dụ: Giải

T(n) = T(n/2) + 1
= T(n/22) + 1 + 1
….
= T(n/2i) + i
Dừng: n/2i = 1 (n0), hay i=log2n, khi đó T(n) = 0 + log2n
05/08/2023 Cấu trúc dữ liệu & Giải thuật 31
Nội dung
• Giới thiệu
• Phân tích trực tiếp các đoạn mã
• Phân tích đoạn mã có lời gọi chương trình con
• Đánh giá dựa trên thực nghiệm
• Bài tập

05/08/2023 Cấu trúc dữ liệu & Giải thuật 32


Đánh giá dựa trên thực nghiệm

05/08/2023 Cấu trúc dữ liệu & Giải thuật 33


Đánh giá dựa trên thực nghiệm

05/08/2023 Cấu trúc dữ liệu & Giải thuật 34


Đánh giá dựa trên thực nghiệm

05/08/2023 Cấu trúc dữ liệu & Giải thuật 35


Đánh giá dựa trên thực nghiệm

05/08/2023 Cấu trúc dữ liệu & Giải thuật 36


Đánh giá dựa trên thực nghiệm

05/08/2023 Cấu trúc dữ liệu & Giải thuật 37


1: sum = 0;
Bài tập về nhà 2: i = 1;
• Bài tập 1: Có bao nhiêu 3: while (i <= n) {
phép so sánh trong 4: j = n – i*i;
đoạn code sau đây? 5: while (j <= i*i) {
6: sum += i*j;
7: j = j + 1;
8: }
9: i = i + 1;
05/08/2023
10:
Cấu trúc dữ liệu & Giải thuật
} 38
1: sum = 0;
Bài tập về nhà 2: i = 1;
• Bài tập 2: Hãy viết 3: while (i <= n) {
chương trình thử 4: j = n – i*i;
nghiệm để đếm số 5: while (j <= i*i) {
phép gán và so sánh 6: sum += i*j;
của đoạn chương trình
sau đây để kiểm tra lại 7: j = j + 1;
lý thuyết? 8: }
9: i = i + 1;
05/08/2023
10:
Cấu trúc dữ liệu & Giải thuật
} 39
Bài tập về nhà
Bài tập 3: Đánh giá độ phức tạp của đoạn chương
trình đệ quy tính giá trị của dãy số Fibonacci
Bài tập 4: Đánh giá độ phức tạp của đoạn chương
trình đệ quy giải bài toán Tháp Hà Nội

05/08/2023 Cấu trúc dữ liệu & Giải thuật 40


double SumDevideFactorial(int n)
Bài tập về nhà {
double S = 1;
double p = 1;
Bài tập 5: Tính  ex for(int i = 0; i < n; i++)
ex  = 1 + ( x/1!) + (x*x/2!) + (x*x*x/ {
3!) + … + (xn /n!) for(int j = 0;  j < i;  j++)
{
Với thuật toán ở bên phải, hãy
tính độ phức tạp của thuật toán p = p*x/ j;
này. S += p;
}
}
return S;
}

05/08/2023 Cấu trúc dữ liệu & Giải thuật 41


double SumDevideFactorial(int n)
Bài tập về nhà {
double S = 1;
Bài tập 6: Tính  ex dựa vào tính double p = 1;
kế thừa, dùng kết quả của bước
for(int i = 0; i < n; i++)
trước, tính số hạng sau qua số
hạng trước: {
x/n! = (x/n ) . (xn-1/(n-1)!) p = p*x/ i;
• Với thuật toán ở bên phải, hãy S += p;
tính độ phức tạp của thuật }
toán này.
return S;
}

05/08/2023 Cấu trúc dữ liệu & Giải thuật 42


Tài liệu tham khảo
• Cấu trúc dữ liệu và Giải thuật (Data Structures
and Algorithms), ĐHCT.
• Cấu trúc dữ liệu và Giải thuật, HV BCVT
• Cấu trúc dữ liệu và Thuật toán, Nguyễn Đức
Nghĩa, ĐH BKHN
• Introduction to Algorithms
• Data Structures and Algorithms in Python
05/08/2023 Cấu trúc dữ liệu & Giải thuật 43
Xin cảm ơn
Hết Chương 1

05/08/2023 Cấu trúc dữ liệu & Giải thuật 44

You might also like