Professional Documents
Culture Documents
Ch 02 - Phân tích thuật toán
Ch 02 - Phân tích thuật toán
2/17/2023 1
1
Các đặc trưng của thuật toán
Input: Là các giá trị cần đưa vào (có thể là rỗng) khi
thực hiện thuật toán.
Output: là kết quả của thuật toán, có quan hệ xác định
với dữ liệu vào.
Tính xác định: Mỗi bước của thuật toán cần mô tả một
cách chính xác.
Tính khả thi: Các phép toán trong các bước của thuật
toán phải đủ đơn giản.
Tính dừng: Thuật toán phải dừng sau hữu hạn bước
ứng với mọi bộ dữ liệu thõa điều kiện đầu vào.
2/17/2023 3
2/17/2023 4
2
Sắp xếp chèn
InsertionSort(A, n) {
for j = 2 to n {
▷ điều kiện: dãy A[1..j-1] được sắp
1. Tìm vị trí i trong dãy A[1..j-1] sao cho A[i] ≤ A[j] < A[i+1]
2. Chèn A[j] vào giữa A[i] và A[i+1]
sorted
2/17/2023 5
sorted Key
2/17/2023 6
3
Sắp xếp chèn
5 2 4 6 1 3
2 5 4 6 1 3
2 4 5 6 1 3
2 4 5 6 1 3
1 2 4 5 6 3
1 2 3 4 5 6 Done!
2/17/2023 7
4
Phương pháp Horner
Biến đổi đa thức p(x):
2/17/2023 9
5
Phương pháp Horner
Mặt khác, khi thế ngược theo các hệ số bi, ta có:
2/17/2023 11
Trong ví dụ trên:
a3 = 2, a2 = -6, a1 = 2, a0 = -1
b3 = 2, b2 = 0, b1 = 2, b0 = 5
Bài tập: Thực hiện phép chia đa thức
x3 – 6x2 + 11x – 6 cho x – 2
4x4 – 6x3 + 3x – 5 cho 2x – 1
2/17/2023 12
6
Các vấn đề liên quan đến thuật toán
Thiết kế thuật toán: tìm ra một thuật toán cho một bài
toán đặt ra.
Tính đúng đắn của thuật toán: thuật toán phải cho
một kết quả đúng với mọi dữ liệu vào hợp lệ.
Phân tích thuật toán: đánh giá độ phức tạp của một
thuật toán.
Tính hiệu quả:
Thuật toán đơn giản, dễ hiểu, dễ cài đặt
7
Độ phức tạp của thuật toán
Đặc tả thuật toán cần chỉ ra các đặc điểm sau:
Các đối tượng thuật toán cần sử dụng (đầu vào)
Điều kiện ràng buộc (nếu có) của dữ liệu đầu vào
2/17/2023 15
8
Phân tích thuật toán Insertion Sort
InsertionSort(A, n) {
for j = 2 to n {
key = A[j]
i = j - 1;
while (i > 0) and (A[i] > key) {
A[i+1] = A[i]
i = i - 1
}
A[i+1] = key
}
} Có bao nhiêu lần
dòng lệnh này được thực thi?
2/17/2023 17
9
Phân tích thuật toán Insertion Sort
Statement cost time__
InsertionSort(A, n) {
for j = 2 to n { c1 n
key = A[j] c2 (n-1)
i = j - 1; c3 (n-1)
while (i > 0) and (A[i] > key) { c4 S
A[i+1] = A[i] c5 (S-(n-1))
i = i - 1 c6 (S-(n-1))
} 0
A[i+1] = key c7 (n-1)
} 0
}
S = t2 + t3 + … + tn với tj là số lần lệnh while thực
hiện tại lần lặp thứ j
2/17/2023 19
10
Các ký hiệu tiệm cận
Các ký hiệu tiệm cận để đánh giá thuật toán, gồm:
O: Big-O
Ω: Big-Omega
Θ: Theta
o: Small-o
ω: Small-omega
Không gian
Cần phân tích thuật toán trong trường hợp xấu nhất
2/17/2023 21
11
Tiệm cận trên (Upper bound)
Cho: f(n) = 3n2 + 10n + 5 O(n2)
Cần tìm các hằng số dương c and n0 sao cho:
f(n) cn2 for all n > n0.
3n2 + 10n + 5 10n2 + 10n + 10
10n2 + 10n2 + 10n2," n 1
30 n2, " n 1
Nếu đặt c = 30 và n0 = 1, thì f(n) c n2, " n ≥ n0.
Theo định nghĩa của big-O thì f(n) = O(n2).
Có thể thấy rằng:
lim n→∞ n2 / (3n2 + 10n + 5) = 1/3 > 0
2/17/2023 23
12
Tiệm cận dưới (Lower bound)
Định nghĩa: f(n) = W(g(n))
g(n)=O(f(n))
Lim g(n) / f(n) exists
n
13
Tiệm cận chặt (Tight bound)
Định nghĩa: f(n) = Q(g(n))
f(n)=O(g(n)) and g(n)=O(f(n))
f(n)=O(g(n)) and f(n)=W(g(n))
Lim g(n)/f(n) and Lim f(n)/g(n) exist
n n
“Theta của g(n) là f(n)” c1g(n)
2/17/2023 28
14
Tiệm cận
Chứng minh rằng:
n2 + 3n + lg n thuộc Ω(n2)
Cần tìm c và n0 sao cho
n2 + 3n + lg n >= cn2 for n > n0
n2 + 3n + lg n >= n2 for n > 0
Ngoài ra:
n2 + 3n + lg n = O(n2)
và n2 + 3n + lg n = Ω (n2)
Suy ra:
n2 + 3n + lg n = Θ(n2)
2/17/2023 29
15
So sánh các tiệm cận
c*g(n) c*f(n) c1g(n)
f(n)
f(n) g(n)
c2g(n)
n n n
k k k
f(n) o(g(n))
0 f(n) O(g(n))
lim f(n) / g(n) = c >0 f(n) Θ (g(n))
n→∞
∞ f(n) Ω(g(n))
f(n) ω (g(n))
2/17/2023 31
16
Các tính chất tiệm cận
Bắc cầu
f(n) = Q(g(n)) and g(n) = Q(h(n))
=> f(n) = Q(h(n))
(giữ nguyên đối với các tiệm cận o, O, w, và W)
Đối xứng
f(n) = Q(g(n)) if and only if g(n) = Q(f(n))
Đối xứng chuyển vị
f(n) = O(g(n)) if and only if g(n) = W(f(n))
f(n) = o(g(n)) if and only if g(n) = w(f(n))
2/17/2023 33
2/17/2023 34
17
Một số công thức hữu ích
Với a > 0, b > 0, c > 0, ta có các luật sau:
• logba = logca / logcb = lg a / lg b
• logban = n logba
• log a
b b = a
• log (ab) = log a + log b
– lg (2n) = ?
• log (a/b) = log (a) – log(b)
– lg (n/2) = ?
– lg (1/n) = ?
• logba = 1 / logab
2/17/2023 35
2/17/2023 36
18
Đánh giá tiệm cận
So sánh 2n và 3n
Vì:
lim 2n / 3n = lim(2/3)n = 0
Nên:
2n o(3n)
3n ω(2n)
Đối với 2n và 2n+1 thì:
2n / 2n+1 = ½,
Vì vậy:
2n = Θ (2n+1)
2/17/2023 37
2/17/2023 38
19
Đánh giá tiệm cận
log2n n nlog2n n2 n3 2n n!
10 3.3 10 33 102 103 103 106
102 6.6 102 660 104 106 1030 10158
103 10 103 104 106 109
104 13 104 105 108 1012
105 17 105 106 1010 1015
106 20 106 107 1012 1018
O is like W is like Q is like = Một siêu máy tính thực hiện 1 nghìn tỷ
phép toán trong 1 giây.
o is like < w is like > Điều đó sẽ mất hơn một tỷ năm.
2/17/2023 39
2/17/2023 40
20
Công thức Stirling
Giai thừa: n! 1 2 3 . . . (n - 2) (n - 1) n
n
n 1
Định lý: n! 2 πn 1 Θ
e n
với e là hằng số Euler = 2.71828…
n
Định lý: n! 2 πn n
e
n n log2 πn
n
Hệ quả: log (n! ) log 2 πn n log
O(n log n)
e
e 2
Vì vậy: 2n = o(n!)
So sánh nn và n!
n! c nn n c n
lim n lim n n lim n 0
n n n n e n e
Vì vậy: nn = ω(n!)
2/17/2023 42
21
Công thức Stirling
Đánh giá tiệm cận của log(n!)
c nnn n 1 / 2
log( n! ) log C log n log( e n
)
en
1
C n log n log n n
2
n n 1
C log n ( log n n ) log n
2 2 2
Q( n log n )
2/17/2023 43
n
n3
i
i 1
2
3
Q( n 3 )
n
1 n Q(n)
i 1
n
i k
n k 1
Q( n k 1 )
i 1 k 1
n
n( n 1)
i
i 1 2
Q( n 2 ) n
i2 i
( n 1)2n 1 2 Q( n 2n )
i 1
n
r n 1 1 Q(1) ( r 1)
n
1
i Q(lg n)
i
r
i 0 r 1 Q( r n ) ( r 1) i 1
n
lg i Q(n lg n)
i 1
2/17/2023 44
22
Một số công thức
2 1
2n 1 1 2n 1
n n
1 1
lim n i lim n ( 1 2)i 2
i 0 2 i 0 1 12
n n
1
lim n n 2 2 2 1 1
i 0
i
lim 1 1
i 1 2 i 0
2/17/2023 45
ca c a
n
i i
i 1
(4i 2i )
i i
n x n
a a a
i m
i
i m
n
i
n
4 i 2i 2n(n 1) 2n 1 2
i x 1
i
i 1 i 1
n n
n 1
i 1 2 i
n
i 1 2 i
n
23
Đánh giá thuật toán
repeatedElement (A, n)
//Xác định các phần tử trong mảng có khác biệt hay không?
for i = 1 to n-1 {
for j = i+1 to n {
if (A[i] == A[j])
return true;
}
}
return false;
Cần đánh giá thuật toán trong các trường hợp:
Tốt nhất nhất (Best case)
Xấu nhất (Worst-case)
Trung bình (Average case)
2/17/2023 47
24
Đánh giá thuật toán
int Euclid(int m, int n)
{
int r;
r = m%n;
while (r != 0) Trước lệnh while là một lệnh đơn.
{ Nếu có k lần lặp lệnh while thì số
m = n; lần kiểm tra điều kiện là (k + 1)
Mỗi lần lặp while, cần thực hiện 3
n = r; lệnh đơn, có độ phức tạp O(1)
r = m%n; Thời gian thực hiện thuật toán phụ
} thuộc vào số lần lệnh while.
return n;
}
2/17/2023 49
25
Đánh giá thuật toán đệ quy
Hàm đệ quy chứa lời gọi đến chính nó. Gọi F là hàm đệ
quy có thời gian chạy T(n), với n là cỡ dữ liệu đầu vào.
Bước 1: Gọi T(m) là thời gian chạy lời gọi đệ quy trong
hàm F, với m < n
Bước 2: Đánh giá thời gian chạy hàm F trên cỡ dữ liệu
nhỏ nhất n = 1. Giả sử T(1) = a, với a là một hằng số.
Bước 3: Tìm quan hệ đệ quy biểu diễn thời gian chạy
của hàm F thông qua lời gọi hàm, tức là biểu diễn T(n)
thông qua các lời gọi T(m), với m < n.
Ví dụ hàm đệ quy F chứa 2 lời gọi đệ quy, khi đó:
T(1) = a, T(n) = f(T(m1), T(m2)), với m1, m2 < n
Bước 4: Thực hiện phép thế lặp để tìm T(n)
2/17/2023 51
26
Đánh giá thuật toán đệ quy
int Fact(int n) Thời gian thực hiện của
{ thuật toán:
T(1) = C1
int kq;
T(n) = C2 + T(n-1)
if (n <= 1) kq = 1;
Thực hiện phép thế lặp:
else kq = kq * Fact(n-1); T(2) = C2 + T(1)
return kq; T(3) = C2 + T(2)
} …
T(n-1) = C2 + T(n-2)
T(n) = C2 + T(n-1).
2/17/2023 53
2/17/2023 54
27
Một số trường hợp đệ quy
Nếu: T(n) = a • T(n/b) + f(n) với a≥1, b>1,
và đặt c = logba thì:
f(n)=O(nc-e) với một vài số e0 T(n)=Q(nc)
f(n)=Q(nc) T(n)=Q(nc log n)
f(n)=W(nc+e) với một vài số e0
và a•f(n/b) ≤ d•f(n)
cho một vài số d<1 " n>n0 T(n)=Q(f(n))
Ví dụ: T(n) = 2T(n/2)+n T(n)=Q(n log n)
T(n) = 9T(n/3)+n T(n)=Q(n2)
T(n) = T(2n/3)+1 T(n)=Q(log n)
2/17/2023 55
28
Hệ thức truy hồi
2/17/2023 57
29
Hệ thức truy hồi
Tìm nghiệm của hệ thức truy hồi an = an-1 + 2an-2,
với a0 = 2 và a1 = 7.
Phương trình đặc trưng là: r2 - r - 2 = 0 có các
nghiệm là r1 = 2 và r2 = -1.
Khi đó an = 12n + 2(-1)n
a 0 = 2 = 1 + 2
a1 = 7 = 1.2 + 2.(-1)
Suy ra: 1 = 3, 2 = -1
Kết luận: nghiệm của hệ thức an = 3.2n - (-1)n
Giải hệ thức truy hồi Fibonacci
fn = fn-1 + fn-2, với f0 = 0, f1 =1
2/17/2023 59
30
Bài tập
Tính độ phức tạp của đoạn chương trình sau:
int kq = 0;
for(int i = 1; I < n; i++)
{
int tam = 0;
for(int j = 1; j <= i; j++)
tam = tam + j*j;
if(i%2 == 0)
kq = kq + tam;
else
kq = kq - tam;
}
2/17/2023 61
Bài tập
Tính độ phức tạp của đoạn chương trình sau:
int kq = 0 ;
for(int i = 0; i < n; i++)
{
int tam = 0;
for(int j = i; j <= n; j++)
{
tam = tam + j*(j+1) ;
for(int k = 0; k <= j; k++)
tam = tam + k*(k-1);
}
if(i%2==0) kq = kq + tam;
else kq = kq - tam;
}
2/17/2023 62
31
Bài tập
Kiểm tra các đánh giá tiệm cận sau:
1. 2n2 + 1 = O(n2) T (also Q)
2. Sqrt(n) = O(log n) F (w)
3. log n = O(sqrt(n)) T (also o)
4. n2(1 + sqrt(n)) = O(n2 log n) F (w)
5. 3n2 + sqrt(n) = O(n2) T (also Q)
6. sqrt(n) log n = O(n) T (also o)
2/17/2023 63
Bài tập
Bài 1: Giải hệ thức truy hồi:
2/17/2023 64
32
XIN TRÂN TRỌNG
CÁM ƠN!
2/17/2023 65
33