Nội dung khóa học Cấu trúc dữ liệu và giải thuật (Chương 1 đến 5)

Nội dung khóa học Cấu trúc dữ liệu và giải thuật (Chương 1 đến 5) bao gồm đầy đủ nội dung của 5 chương của Đại học Bách Khoa Hà Nội với những kiến thức và thông tin bổ ích giúp sinh viên tham khảo, ôn luyện và phục vụ nhu cầu học tập của mình cụ thể là có định hướng ôn tập, nắm vững kiến thức môn học và làm bài tốt trong những bài kiểm tra, bài tiểu luận, bài tập kết thúc học phần, từ đó học tập tốt và có kết quả cao cũng như có thể vận dụng tốt những kiến thức mình đã học vào thực tiễn cuộc sống. Mời bạn đọc đón xem!

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
Cấu trúc dữ liệu giải thuật
Nguyễn Khánh Phương
Computer Science department
School of Information and Communication technology
E-mail: phuongnk@soict.hust.edu.vn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Nidung khóahc
Chương 1. Các khái niệm bản
Chương 2. Các cấu trúc dữ liệu bản
Chương 3. Cây
Chương 4. Sắp xếp
Chương 5. Tìm kiếm
2
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
Chương 1. Các khái niệm bản
Nguyễn Khánh Phương
Computer Science department
School of Information and Communication technology
E-mail: phuongnk@soict.hust.edu.vn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ni dung
1.1. dụ mở đầu
1.2. Thuật toán độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số thuật phân tích thuật toán
1.6. Giải công thức đệ quy
4
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ni dung
1.1. dụ mở đầu
1.2. Thuật toán độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số thuật phân tích thuật toán
1.6. Giải công thức đệ quy
5
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: Tìm dãy con lớn nhất
(The maximum subarray problem)
Cho dãy số gồm n số:
a
1
, a
2
,…,a
n
Dãygmliêntiếpcács a
i
,a
i+1
,…,a
j
với 1 i j n được gọi
dãy
con
của dãy đã cho
𝑎

đượcgilàtrng lượng ca dãy con này
Bàitoátralà:Hãytìmtrnglưnglnnhtcacácdãycon,tclà
tìm cực đại giá trị
𝑎

. Ta gọi dãy con trọng lượng lớn nhất dãy
con lớn nhất.
dụ: Cho dãy số -2, 11, -4, 13,-5,2thì cưaracâutrảlilà20(dãycon
lớn nhất 11, -4, 13 với giá trị = 11+ (-4)+13 =20 )
Để giải bài toán này, ta có thể dùng nhiều cách khác nhau, du duyệt toán
bộ (brute force), chia để chị (divide and conquer), quy hoạch động (dynamic
programming), ...
6
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: Tìm dãy con lớn nhất
(The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming)
7
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: Tìm dãy con lớn nhất
(The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming)
8
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.1. Thuật toán duyệt toàn bộ giải bài toán dãy con lớn nhất
Thuật toán đơn giản đầu tiên thể nghĩ để giải bài toán đặt
ra là: Duyệt tất cả các dãy con thể :
a
i
,a
i+1
,…,a
j
với 1 i j n,
tính tổng của mỗi dãy con để tìm ra trọng lượng lớn nhất.
Trước hết nhận thấy rằng, tổng số các dãy con thể của
dãy đã cho là:
C(n, 1) + C(n, 2) = n
2
/2 + n/2
9
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ ứng dụng
Giả sử ta biết giá của cổ phiếu của công ty A từ ngày i đến ngày j như sau:
Ta cần mua một số cổ phiếu,
duy nhất 1 lần, rồi bán ra tại một ngày nào đó sau đấy.
Làm thế nào để tối đa hóa lợi nhuận ?
Chiến lược: mua vào lúc giá thấp, bán ra lúc giá cao [buy low, sell high] không phải lúc nào cũng
cho lợi nhuận cao nhất
dụ: Cho giá cổ phiếu như ở đồ thị. Ta thu được lợi nhuận cao nhất 3$ nếu mua vào ở thứ 2 với giá
7$, và bán ra ở ngày thứ 3 với giá 10$. Giá 7$ mua vào ở ngày 2 không phải là giá thấp nhất, và giá 10$
bán ra ở ngày 3 cũng không phải là giá cao nhất
Lời giải: Ta dễ dàng tìm được bằng cách duyệt hết tất cả các khả năng:
bao nhiêu cặp ngày mua/bán thể trong khoảng thời gian n ngày?
Tính lợi nhuận thu được cho mỗi cặp ngày, để tìm cặp ngày lợi nhuận cao nhất
Liệu ta có thể làm tốt hơn hay không?
Câu trả lời: Có, bằng cách quy về bài toán dãy con lớn nhất
Ngày
1234567891011121314151617
Giá
100 112 109 85 105 102 86 63 81 101 94 106 101 79 93 89 95
10
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Quy về bài toán dãy con lớn nhất
Tìm dãy các ngày liên tiếp sao cho:
Tổng lượng giá thay đổi ở ngày cuối so với ngày đầu lớn nhất
Nhìnvàogiácatngngày
Lượng giá thay thay đổi vào ngày i: giá cổ phiếu ngày i trừ đi giá cổ phiếu ngày i-1
Ta có mảng giá thay đổi như sau:
Tìm dãy con liên tiếp tổng lớn nhất
Dãy con lớn nhất
e.g.: 12,-3,-24,20,-3,-16,-23,
18,20,-7,12,-5,-22,14,-4,6
Mua sau ngày thứ 7, bán ra sau ngày thứ 11: mua với giá = 63, bán ra với lúc = 106
Lợi nhuận =106-63=43
Dãy con lớn nhất: 18+20+(-7)+12 = 43
Ngày
1234567891011121314151617
Giá
100 112 109 85 105 102 86 63 81 101 94 106 101 79 93 89 95
Ngày
1234567891011121314151617
Giá
100 112 109 85 105 102 86 63 81 101 94 106 101 79 93 89 95
Thay
đổi
123 2420‐3 16231820‐7 12‐5 221446
11
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
i = 0: (-2), (-2, 11), (-2,11, -4), (-2,11,-4,13), (-2,11,-
4,13,-5), (-2,11,-4,13,-5,2)
i = 1: (11), (11, -4), (11, -4, 13), (11, -4, 13, -5), (11, -4,
13, -5, 2)
i = 2: (-4), (-4, 13), (-4, 13, -5), (-4,13,-5,2)
i = 3: (13), (13,-5), (13, -5,2)
i = 4: (-5), (-5, 2)
i = 5: (2)
Chsi012345
a[i] ‐2 11 ‐4 13 ‐5 2
int maxSum = 0;
for (int i=0; i<n; i++) {
for (int j=i; j<n; j++) {
int sum = 0;
for (int k=i; k<=j; k++)
sum += a[k];
if (sum > maxSum)
maxSum = sum;
}
}
12
Với mỗi chỉ số i : duyệt tất cả các dãy con bắt đầu từ phần tử
a[i] có1 phnt, có2 phnt, :
i = 0: tất cả các dãy con bắt đầu từ a[0] có 1 phần tử, 2 phần
tử, … 6 phần tử
i = 1: tất cả các dãy con bắt đầu từ a[1] có 1 phần tử, 2 phần
tử, … 5 phần tử
i = 5: tất cả các dãy con bắt đầu từ a[5] có 1 phần tử
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
Phân tích thuật toán: Ta sẽ tính số lượng phép cộng thuật toán phải thực hiện, tức đếm
xem dòng lệnh
sum += a[k]
phải thực hiện bao nhiều lần. Số lượng phép cộng là:
int maxSum = 0;
for (int i=0; i<n; i++) {
for (int j=i; j<n; j++) {
int sum = 0;
for (int k=i; k<=j; k++)
sum += a[k];
if (sum > maxSum)
maxSum = sum;
}
}
11 1 1
00 0
2
111
32
()( 1)
(1)(12...())
2
1 1 1 ( 1)(2 1) ( 1)
(1)
22 262
623
nn n n
iji i i
nnn
kkk
nini
ji ni
nn n nn
kk k k
nnn













13
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: Tìm dãy con lớn nhất
(The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming)
14
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.2. Duyệt toàn bộ cải tiến
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
i = 0: (-2), (-2, 11), (-2,11, -4), (-2,11,-4,13), (-2,11,-4,13,-5), (-2,11,-
4,13,-5,2)
i = 1: (11), (11, -4), (11, -4, 13), (11, -4, 13, -5), (11, -4, 13, -5, 2)
i = 2: (-4), (-4, 13), (-4, 13, -5), (-4,13,-5,2)
i = 3: (13), (13,-5), (13, -5,2)
i = 4: (-5), (-5, 2)
i = 5: (2)
Chsi012345
a[i] ‐2 11 ‐4 13 ‐5 2
15
int maxSum = 0;
for (int i=0; i<n; i++) {
for (int j=i; j<n; j++) {
int sum = 0;
for (int k=i; k<=j; k++)
sum += a[k];
if (sum > maxSum)
maxSum = sum;
}
}
15
int maxSum = a[0];
for (int i=0; i<n; i++) {
int sum = 0;
for (int j=i; j<n; j++) {
sum += a[j];
if (sum > maxSum)
maxSum = sum;
}
}
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.2. Duyệt toàn bộ cải tiến
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
Cài đặt cải tiến:
Nhận thấy, ta có thể tính tổng các phần tử từ vị trí
i đến j từ tổng của các phần
tử từ
i đến j-1 chỉ bằng 1 phép cộng:
int maxSum = 0;
for (int i=0; i<n; i++) {
for (int j=i; j<n; j++) {
int sum = 0;
for (int k=i; k<=j; k++)
sum += a[k];
if (sum > maxSum)
maxSum = sum;
}
}
1
[] [] []
jj
ki ki
ak a j ak



Tổng các phần tử từ i đến j
Tổng các phần tử từ i đến j-1
int maxSum = a[0];
for (int i=0; i<n; i++) {
int sum = 0;
for (int j=i; j<n; j++) {
sum += a[j];
if (sum > maxSum)
maxSum = sum;
}
}
16
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.2. Duyệt toàn bộ cải tiến
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
Phân tích thuật toán. Ta lại tính số lần thực hiện phép cộng:
Sum += a[j]
thu được kết quả:
Để ý rằng số này đúng bằng số lượng dãy con. Dường như thuật toán thu được
rất tốt, ta phải xét mỗi dãy con đúng 1 lần.
int maxSum = a[0];
for (int i=0; i<n; i++) {
int sum = 0;
for (int j=i; j<n; j++) {
sum += a[j];
if (sum > maxSum)
maxSum = sum;
}
}
2
1
0
( ) ( 1) ... 1
22
n
i
nn
ni n n

17
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: Tìm dãy con lớn nhất
(The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming)
18
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
Tacòncóthểxâydngthuttoántthơnnabngkỹthutchiểtr
(divide-and-conquer). Kỹ thuật này bao gồm các bước sau:
Chia bài toán cần giải ra thành các bài toán con cùng dạng
Giải mỗi bài toán con một cách đệ qui
Trường hpcơ s: khi bài toán con kích thước đủ nh,tagii
bng phương pháp duyt toàn b.
Tổ hợp lời giải của các bài toán con để thu được lời giải của bài toán
xuất phát.
Để giải bài toán dãy con lớn nhất:
Sử dụng phần tử chính giữa để chia đôi dãy đã cho thành hai dãy con (gọi tắt
dãy nửa trái dãy nửa phải) với độ dài giảm đi một nửa
low mid high
mid +1
Nửa trái A[low..mid]
Nửa phải A[mid+1..high]
19
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
Để tổ hợp lời giải, nhận thấy rằng dãy con lớn nhất A[i..j] của dãy A[low..high] chỉ thể xảy ra một
trong 3 trường hợp (với mid = (low+high)/2):
Dãy con lớn nhất nằm ở dãy nửa bên trái A[low..mid] (low i j mid)
Dãy con lớn nhất nằm ở dãy nửa bên phải A[mid+1..high] (mid < i j high)
Giao điểm giữa mid (low i mid < j high) {dãy con lớn nhất bắt đầu ở nửa trái kết thúc ở nửa
phải}
Do đó, nếu hiệu trọng lượng của dãy con lớn nhất nửa trái w
L
,ởnaphilàw
R
, giao điểm giữa
w
M
, thì trọng lượng lớn nhất cần tìm
max(w
L
,w
R
,w
M
)
20
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
Việc tìm trọng lượng của dãy con lớn nhất nửa trái (w
L
)vànaphi (w
R
) thể thực hiện một cách đệ
quy:
Trường hợp sở (base case): dãy nửa trái / phải chỉ gồm duy nhất 1 phần tử
Để tìm trọng lượng w
M
của dãy con lớn nhất bắt đầu từ nửa trái kết thúc nửa phải, ta thực hiện như
sau:
dãy nửa trái: tìm trọng lượng w
ML
của dãy con lớn nhất kết thúc điểm chia mid
dãy nửa phải: tính trọng lượng w
MR
của dãy con lớn nhất bắt đầu vị trí mid+1
Khi đó w
M
=w
ML
+w
MR
.
21
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: tính trọng lượng w
M
của dãy con lớn nhất bắt đầu ở dãy nửa trái kết
thúc ở dãy nửa phải
12345678910
13 ‐3 ‐25 20 ‐3 ‐16 ‐23 18 20 ‐7
A
S[5 .. 5] = -3
S[4 .. 5] = 17 (max_left = 4)
S[3 .. 5] = -8
S[2 .. 5] = -11
S[1 .. 5] = 2
mid =5
12345678910
13 ‐3 ‐25 20 ‐3 ‐16 ‐23 18 20 ‐7
A
S[6 .. 6] = -16
S[6 .. 7] = -39
S[6 .. 8] = -21
S[6 .. 9] = (max_right = 9) -1
S[6..10] = -8
mid =5
Ởdãy nửa trái:
Ởdãy nửa phải:
Dãy con lớn nhất giao điểm chia mid S[4..9] = 17+ (-1) = 16
22
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Tính trọng lượng w
M
của dãy con lớn nhất bắt đầu ở dãy nửa trái kết thúc
dãy nửa phải
dãy nửa trái: tìm trọng lượng w
ML
của dãy con lớn nhất kết thúc điểm chia mid
dãy nửa phải: tính trọng lượng w
MR
của dãy con lớn nhất bắt đầu vị trí mid+1
Khi đó w
M
=w
ML
+w
MR
.
wM = MaxLeft(a,low,mid) + MaxRight(a,mid,high);
23
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
Phân tích thuật toán: Ta cần tính xem lệnh gọi MaxSub(a,1,n) để thực hiện thuật toán đòi hỏi
bao nhiêu phép cộng?
Thủ tục MaxLeft MaxRight yêu cầu
n/2 + n/2 = n phép cộng
vậy, nếu gọi T(n) là số phép cộng lệnh maxSub(a, 1, n) cần thực hiện, ta có công
thức đệ quy sau:
Giải công thức đệ quy này, ta có
T(n) = n log n
0 1
()
( ) ( ) 2 ( ) 1
22 2
n
Tn
nn n
TTnTn n

24
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
dụ: để tìm dãy con lớn nhất cho mảng a gồm 10 phần tử cho ở bảng dưới đây
Ta sẽ phải gọi lệnh: MaxSub(a, 1, 10)
25
12345678910
13 ‐3 ‐25 20 ‐3 ‐16 ‐23 18 20 ‐7
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài toán dãy con lớn nhất: so sánh thời gian tính của các thuật toán
Số lương phép cộng mỗi thuật toán cần thực hiện là:
1.1.1. Duyệt toàn bộ
1.1.2. Duyệt toàn bộ cải tiến
1.1.3 Thuật toán đệ quy: n log n
Cùng một bài toán, ta đã đề xuất 3 thuật toán đòi hỏi số lượng phép toán khác nhau,
thế sẽ đòi hỏi thời gian tính khác nhau.
Bảng dưới đây cho thấy thời gian tính của 3 thuật toán trên, với giả thiết: máy tính
thể thực hiện10
8
phép cộng trong một giây
Độ phức tạp n=10 Thời gian n=100 Thời gian
n
3
10
3
10
-5
giây 10
6
10
-2
giây
n
2
100 10
-6
giây 10000 10
-4
giây
nlogn 33.2 3.3*10
-8
giây 664 6.6*10
-6
giây
e
n
2.2*10
4
1*10
-4
giây 2.69*10
43
>10
26
thế k
n=10
4
Thời gian n=10
6
Thời gian
10
12
2.7hours 10
18
115ngày
10
8
1giây 10
12
2.7giờ
1.33*10
5
10
‐3
giây 1.99*10
7
2*10
‐1
sec
8.81*10
4342
>10
4327
thế k
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài toán dãy con lớn nhất: so sánh thời gian tính của các thuật toán
Với n nhỏ thời gian tính không đáng kể.
Vấn đề trở nên nghiêm trọng hơn khi n >10
6
. Lúc đó chỉ thuật
toán thứ ba (thời gian nlogn) thể áp dụng được trong thời gian
thực.
Còn thể làm tốt hơn nữa không?
Yes! thể đề xuất thuật toán chỉ đòi hỏi n phép cộng!
27
Độ phức tạp n=10 Thời gian n=100 Thời gian
n
3
10
3
10
-5
giây 10
6
10
-2
giây
n
2
100 10
-6
giây 10000 10
-4
giây
nlogn 33.2 3.3*10
-8
giây
664 6.6*10
-6
giây
e
n
2.2*10
4
1*10
-4
giây 2.69*10
43
>10
26
thế k
n=10
4
Thời gian n=10
6
Thời gian
10
12
2.7hours 10
18
115ngày
10
8
1giây 10
12
2.7giờ
1.33*10
5
10
‐3
giây 1.99*10
7
2*10
‐1
sec
8.81*10
4342
>10
4327
thế k
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: Tìm dãy con lớn nhất
(The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ cải tiến
1.1.3. Thuật toán đệ quy (Recursive algorithm)
n log n
1.1.4. Thuật toán Quy hoạch động (Dynamic programming)
n
28
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất
Thuật toán quy hoạch động được chia làm 3 giai đoạn:
1. Phân (Divide): chia bài toàn cần giải thành những bài toán con
(Bài toán con (Subproblem): là bài toán cùng dạng với bài toán đã
cho, nhưng kích thước nhỏ hơn)
2. Ghi nhận lời giải: lưu trữ lời giải của các bài toán con vào 1 bảng
3. Tổng hợp lời giải: Lần lượt từ lời giải của các bài toán con kích
thước nhỏ hơn tìm cách xây dựng lời giải của bài toán kích thước lớn
hơn, cho đến khi thu được lời giải của bài toán xuất phát (là bài toán
concókíchthưclnnht).
29
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất
Thuật toán quy hoạch động được chia làm 3 giai đoạn:
1. Phân rã:
Gọi s
i
trọng lượng của dãy con lớn nhất của dãy a
1
, a
2
, ..., a
i
, i = 1, 2, ..., n.
ràng, s
n
giá trị cần tìm (lời giải của bài toán).
3. Tổng hợp lời giải:
s
1
= a
1
Giả sử i > 1 và ta đã biết giá trị s
k
với k = 1, 2, ..., i-1. Ta cần tính giá trị s
i
trọng lượng của dãy con lớn nhất
của dãy:
a
1
, a
2
, ..., a
i-1
, a
i
.
Nhận thấy rằng: dãy con lớn nhất của dãy a
1
, a
2
,...,a
i-1
, a
i
thể hoặc bao gồm phần tử a
i
hoặc không bao gồm
phần tử a
i
do đó, dãy con lớn nhất của dãy a
1
, a
2
, ..., a
i-1
, a
i
chỉ thể một trọng 2 dãy sau:
Dãy con lớn nhất của dãy a
1
,a
2
, ..., a
i-1
Dãy con lớn nhất của dãy a
1
,a
2
, ..., a
i
, dãy con này kết thúc tiphnt a
i
.
Do đó, ta s
i
=max{s
i-1
, e
i
},i=2,…,n.
với e
i
trọng lượng của dãy con lớn nhất a
1
,a
2
, ..., a
i
dãy con này kết thúc tại a
i
.
Để tính e
i
, ta xây dng công thc đệ quy:
e
1
= a
1
;
e
i
= max {a
i
, e
i-1
+ a
i
}, i= 2, ..., n.
30
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất
Thuật toán quy hoạch động được chia làm 3 giai đoạn:
1. Phân rã:
Gọi s
i
trọng lượng của dãy con lớn nhất của dãy a
1
, a
2
, ..., a
i
, i = 1, 2, ..., n.
ràng, s
n
giá trị cần tìm (lời giải của bài toán).
3. Tổng hợp lời giải:
s
1
= a
1
Giả sử i > 1 và ta đã biết giá trị s
k
với k = 1, 2, ..., i-1. Ta cần tính giá trị s
i
trọng lượng của dãy con lớn nhất
của dãy:
a
1
, a
2
, ..., a
i-1
, a
i
.
Nhận thấy rằng: dãy con lớn nhất của dãy a
1
, a
2
,...,a
i-1
, a
i
thể hoặc bao gồm phần tử a
i
hoặc không bao gồm
phần tử a
i
do đó, dãy con lớn nhất của dãy a
1
, a
2
, ..., a
i-1
, a
i
chỉ thể một trọng 2 dãy sau:
Dãy con lớn nhất của dãy a
1
,a
2
, ..., a
i-1
Dãy con lớn nhất của dãy a
1
,a
2
, ..., a
i
, dãy con này kết thúc tiphnt a
i
.
Do đó, ta s
i
=max{s
i-1
, e
i
},i=2,…,n.
với e
i
trọng lượng của dãy con lớn nhất a
1
,a
2
, ..., a
i
dãy con này kết thúc tại a
i
.
Để tính e
i
, ta xây dng công thc đệ quy:
e
1
= a
1
;
e
i
= max {a
i
, e
i-1
+ a
i
}, i= 2, ..., n.
31
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất
MaxSub(a)
{
smax = a[1]; // smax : trọng lượng của dãy con lớn nhất
ei = a[1]; // ei: trọng lượng của dãy con lớn nhất kết thúc tại phần tử a[i]
imax = 1; // imax : chỉ số của phần tử cuối cùng thuộc dãy con lớn nhất
for i = 2 to n {
u = ei + a[i];
v = a[i];
if (u > v) ei = u
else ei = v;
if (ei > smax) {
smax := ei;
imax := i;
}
}
}
Phân tích thuật toán:
Số phép cộng phải thực hiện trong thuật toán
= Số lần thực hiện câu lệnh
u = ei + a[i]
= n
32
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
So sánh 4 thuật toán
Bảng sau cho thấy ước tính thời gian tính của 4 thuật toán đề xuất trên
(với giả thiết máy tính thể thực hiện 10
8
phép cộng trong 1 giây)
dụ này cho ta thấy việc phát triển được thuật toán hiệu quả thể
giảm bớt được chi phí thời gian một cách đáng kể như thế nào.
Thuật toán Độ phức tạp n=10
4
Thời gian n=10
6
Thời gian
Duyệt toàn bộ
n
3
10
12
2.7giờ 10
18
115ngày
Duyệt toàn bộ
cải tiến
n
2
10
8
1giây 10
12
2.7giờ
Đệ quy
(Recursive)
nlogn 1.33*10
5
10
‐3
giây 1.99*10
7
2*10
‐1
giây
Quy hoạch động
(Dynamic
programming)
n10
4
10
‐4
giây 10
6
2*10
‐2
giây
33
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ni dung
1.1. dụ mở đầu
1.2. Thuật toán độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số thuật phân tích thuật toán
1.6. Giải công thức đệ quy
34
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Thuật toán (Algorithm)
Thuật ngữ algorithm xuất phát từ tên của nhà toán học người Ba Tư: Abu Ja’far
Mohammed ibn-i Musa al Khowarizmi.
Trong ngành khoa học máy tính, thuật ngữ “thuật toán” được dùng để chỉ một
phương pháp bao gồm một chuỗi các câu lệnh máy tính thể sử dụng để giải
quyết một bài toán.
Định nghĩa. Ta hiểu thuật toán giải bài toán đặt ra là một thủ tục xác định bao gồm
một dãy hữu hạn các bước cần thực hiện để thu được đầu ra (output) cho một đầu
vào cho trước (input) của bài toán.
dụ: Bài toán tìm số nguyên lớn nhất trong một dãy các số nguyên dương cho
trước
Đầu vào (Input) : dãy gồm n số nguyên dương a
1
, a
2
, …, a
n
Đầu ra (Output): số giá trị lớn nhất của dãy đã cho
dụ: Input 12 8 13 9 11 Output: 12
Yêu cầu: thiết kế thuật toán giải bài toán trên
Algorithm
Input
Output
35
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ: Tìm số lớn nhất trong dãy số gồm 5 số nguyên sau:
36
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Các bước trong thuật toán FindLargest
Đặt Largest=phần tử đầu tiên của y
Nếu phần tử thứ hai lớn hơn Largest:đặt Largest=phần tử thứ hai của y
Nếu phần tử thứ ba lớn hơn Largest:đặt Largest=phần tử thứ ba của dãy
Nếu phần tử thứ lớn hơn Largest:đặt Largest=phần tử thứ của dãy
Nếu phần tử thứ năm lớn hơn Largest:đặt Largest=phần tử thứ năm của dãy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
FindLargest chỉnh sửa cho hợp
Đặt Largest=0
Nếu số hiện tại lớn hơn Largest,đặt Largest=số hiện tại
Nếu số hiện tại lớn hơn Largest,đặt Largest=số hiện tại
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Tổng quát hàm FindLargest
Đặt Largest=0
Nếu số hiện tại lớn hơn Largest,đặt Largest=số hiện tại
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Thuật toán
Thuật toán có các đặc trưng sau đây:
Đầu vào (Input): Thuật toán nhận dữ liệu vào từ một tập nào đó.
Đầu ra (Output): Với mỗi tập các dữ liệu đầu vào, thuật toán đưa ra các dữ liệu
tương ứng với lời giải của bài toán.
Chính xác (Precision): Các bước của thuật toán được tả chính xác.
Hữu hạn (Finiteness): Thuật toán cần phải đưa được đầu ra sau một số hữu hạn
(có thể rất lớn) bước với mọi đầu vào.
Đơn trị (Uniqueness): Các kết quả trung gian của từng bước thực hiện thuật
toán được xác định một cách đơn trị chỉ phụ thuộc vào đầu vào các kết quả
của các bước trước.
Tổng quát (Generality): Thuật toán thể áp dụng để giải mọi bài toán
dạng đã cho.
40
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài toán: Thiết kế chương trình sắp xếp n >= 1 s nguyên theo thứ tự không giảm
Input: Tập n số nguyên: a[1], a[2],…, a[n]
Output: Tập n số nguyên đã được sắp xếp: a[1] a[2] ... a[n]
Bước I – Phân tích
Từ dãy số chưa được sắp xếp, ta tìm số nhỏ nhất đặt số này vào vị trí tiếp theo
trong dãy đã sắp xếp
Bước II – Thuật toán
for (i = 1; i <= n; i++){
Trong dãy các phần tử t a[i] đến a[n] tìm phần tử giá trị nhỏ nhất, giả sử
số nguyên nhỏ nhất tìm được a[index_min] với i index_min n;
Hoán đổi vị trí a[i] a[index_min];
}
Bước III – Cài đặt
dụ: Xây dựng thuật toán giải bài toán
41
dụ:Mảng gồm 6số nguyên
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Độ phức tạp của thuật toán
Cho 2 thuật toán cùng giải một bài toán cho trước, làm thế nào để xác định thuật toán nào tốt
hơn?
Khi nói đến hiệu quả của một thuật toán, ta quan tâm đến chi phí cần dùng để thực hiện nó:
1) Dễ hiểu, dễ cài đặt, dễ sửa đổi?
2) Thời gian sử dụng CPU? THỜI GIAN
3) Tài nguyên bộ nhớ? BỘ NHỚ
Trong giáo trình này ta đặc biệt quan tâm đến đánh giá thời gian cần thiết để thực hiện thuật toán
ta sẽ gọi thi gian tính của thuật toán.
42
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Làm thế nào để đo được thời gian tính
Mọi thuật toán đều thực hiện chuyển đổi đầu vào thành đầu ra:
Thời gian tính của thuật toán phụ thuộc vào dữ liệu vào (kích thước tăng, thì thời gian
tăng).
Định nghĩa. Ta gi kích thước d liu đầu vào (hay độ dài d liu vào) là s bít
cn thiết để biu din nó.
Vậy, ta sẽ tìm cách đánh giá thời gian tính của thuật toán bởi một hàm của độ dài
dữ liệu đầu vào.
Tuy nhiên, trong một s trường hợp, kích thước dữ liệu đầu vào như nhau, nhưng
thời gian tính lại rất khác nhau
dụ: Để tìm số nguyên tố đầu tiên trong dãy: ta duyệt dãy từ trái sang phải
Dãy 1: 3 9 8 12 15 20 (thuật toán dừng ngay khi xét phần tử đầu tiên)
Dãy 2: 9 8 3 12 15 20 (thuật toán dừng khi xét phần tử thứ ba)
Dãy 3: 9 8 12 15 20 3 (thuật toán dừng khi xét phần tử cuối cùng)
3 loại thời gian tính
Thuật toán
sắp xếp
5132 1325
Đầu vào Đầu ra
43
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Các loại thời gian tính
Thời gian tính tốt nhất (Best-case):
T(n) : Thời gian tối thiểu cần thiết để thực hiện thuật toán với mọi bộ dữ liệu đầu
vào kích thước n.
Dùng với các thuật toán chậm chạy nhanh với một vài đầu vào.
Thời gian tính trung bình (Average-case):
T(n) : Thời gian trung bình cần thiết để thực hiện thuật toán trên tập hữu hạn các đầu
vào kích thước n.
Rất hữu ích, nhưng khó xác định
Thời gian tính tồi nhất (Worst-case):
T(n) : Thời gian nhiều nhất cần thiết để thực hiện thuật toán với mọi bộ dữ liệu đầu
vào kích thước n. Thời gian như vậy sẽ được gọi là thi gian tính ti nht của thuật
toán với đầu vào kích thước n.
Dễ xác định
hai cách để đánh giá thời gian tính:
Từ thời gian chạy thực nghiệm
thuyết: khái niệm xấp xỉ tiệm cận
0
20
40
60
80
100
120
Running Time
1000 2000 3000 4000
In
p
ut Size
best case
average case
worst case
44
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Phân tích thời gian tính của thuật toán bằng thời gian chạy thực nghiệm
Ta có thể đánh giá thuật toán bằng phương pháp thực nghiệm thông qua việc t
thuật toán, rồi chọn các bộ dữ liệu đầu vào thử nghiệm:
Viết chương trình thực hiện thuật toán
Chạy chương trình với các dữ liệu đầu vào kích thước khác nhau
Sử dụng hàm
clock( ) để đo thời gian chạy chương trình
Vẽ đồ thị kết quả
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
0 50 100
Input Size
Time (ms)
45
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Nhược điểm của việc đánh giá thời gian tính của thuật toán dựa vào thời gian
chạy thực nghiệm chương trình
Bắc buộc phải cài đặt chương trình thì mới thể đánh giá được thời gian
tính của thuật toán. Do phải cài đặt bằng một ngôn ngữ lập trình cụ thể nên
thuật toán sẽ chịu sự hạn chế của ngữ lập trình này. Đồng thời, hiệu quả của
thuật toán sẽ bị ảnh hưởng bởi trình độ của người cài đặt.
Kết quả thu được sẽ không bao gồm thời gian chạy của những dữ liệu đầu
vào không được chạy thực nghiệm. Do vậy, cần chọn được các bộ dữ liệu
thử đặc trưng cho tất cả tập các dữ liệu vào của thuật toán rất khó khăn
tốn nhiều chi phí.
Để so sánh thời gian tính của hai thuật toán, cần phải chạy thực nghiệm hai
thuật toán trên cùng một máy, và sử dụng cùng một phần mềm.
Do đó người ta đã tìm kiếm những phương pháp đánh giá thuật toán hình
thức hơn, ít phụ thuộc môi trường cũng như phần cứng hơn. Một phương
pháp như vậy là phương pháp đánh giá thuật toán theo hướng xấp xỉ tiệm
cận
46
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Phân tích thuyết thời gian tính của thuật toán
Sử dụng giả ngôn ngữ (pseudo-code) để tả thuật toán, thay tiến
hành cài đặt thực sự
Phân tích thời gian tính của thuật toán như hàm của kích thước dữ
liệu đầu vào, n
Phân tích tất cả các trường hợp thể của dữ liệu đầu vào
Cho phép ta có thể đánh giá thời gian tính của thuật toán không bị phụ
thuộc vào phần cứng/phần mềm chạy chương trình (Thay đổi phần
cứng/phần mềm chỉ làm thay đổi thời gian chạy một lượng hằng số,
chứ không làm thay đổi tốc độ tăng của thời gian tính)
47
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ni dung
1.1. dụ mở đầu
1.2. Thuật toán độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số thuật phân tích thuật toán
1.6. Giải công thức đệ quy
48
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.3. Kí hiệu tiệm cận (Asymptotic notation)
, O, o,
» Những hiệu này:
Được sử dụng để tả thời gian tính của thuật toán, tả tốc độ tăng
của thời gian chạy phụ thuộc vào kích thước dữ liệu đầu vào.
Được xác định đối với các hàm nhận giá trị nguyên không âm
Dùng để so sánh tốc độ tăng của 2 hàm
dụ: f(n) = (n
2
): mô tả tốc độ tăng của hàm f(n) và n
2
.
» Thay cố gắng tìm ra một công thức phức tạp để tính chính xác thời gian
tính của thuật toán, ta nói thời gian tính cỡ
n
2
) [đọc theta n
2
]: tức là,
thời gian tính tỉ lệ thuận với n
2
cộng thêm các đa thức bậc thấp hơn
49
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
hiệu Theta
Đối với hàm g(n) cho trước, ta kí hiệu 𝚯(g(n)) tập các hàm
(g(n)) = {f(n): tồn tại các hằng số c
1
, c
2
n
0
sao cho
0 c
1
g(n) f(n) c
2
g(n), với mọi n n
0
}
(tập tất cả các hàm cùng tốc độ tăng với hàm g(n)).
•Hàmf(n) thuộc vào tập 𝚯(g(n)) nếu tồn tại hằng số dương c
1
c
2
sao cho
bị “kẹp”giữa c
1
g(n)vàc
2
g(n)vigiátrn đủ lớn
•𝑓
𝑛𝚯(g(n)) tức tồn tại hằng số c
1
and c
2
sao cho
c
1
g(n)
f(n)≤c
2
g(n) với giá trị n đủ lớn.
Ta nói g(n) là đánh giá tiệm cận đúng cho f(n)
viết 𝑓
𝑛𝚯(g(n))
Khi ta nói một hàm theta của hàm khác,
nghĩa không hàm nào đạt tới giá trị
cùng nhanh hơn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 1: Chứng minh rằng 10n
2
-3n = 𝚯(n
2
)
Ta cần chỉ ra với những giá trị nào n
0
, c
1
, c
2
thì bất đẳng thức trong định
nghĩa của hiệu theta là đúng:
𝑐
𝑛
𝑓󰇛𝑛󰇜 10𝑛
3𝑛𝑐
𝑛
n n
0
Gợi ý: lấy c
1
nhỏ hơn hệ số của số hạng với số cao nhất, c
2
lấy lớn
hơn.
Chọn: c
1
= 1, c
2
= 11, n
0
= 1 thì ta có
n
2
10n
2
3n 11n
2
, vin 1.
n 1: 10n
2
-3n = 𝚯(n
2
)
Chú ý: Với các hàm đa thức: để so sánh tốc độ tăng, ta cần nhìn vào số hạng
số cao nhất
f(n) = (g(n)) c
1
, c
2
, n
0
>0 : n n
0
, c
1
g(n) f(n) c
2
g(n)
51
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 2: Chứng minh rằng 𝑓 𝑛
𝑛
3𝑛𝚯󰇛𝑛
󰇜
Ta cần tìm n
0
, c
1
c
2
sao cho
𝑐
𝑛
𝑓󰇛𝑛󰇜
𝑛
3𝑛𝑐
𝑛
n n
0
Chọn c
1
= ¼, c
2
= 1, và n
0
= 7 ta có:
1
4
𝑛
𝑓 𝑛
1
2
𝑛
3𝑛𝑛
∀ 𝑛 7
∀ 𝑛 7:
𝑛
3𝑛𝚯󰇛𝑛
󰇜
f(n) = (g(n)) c
1
, c
2
, n
0
>0 : n n
0
, c
1
g(n) f(n) c
2
g(n)
52
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 3: Chứng minh rằng f(n) = 23n
3
10 n
2
log
2
n + 7n + 6 𝚯󰇛𝑛
󰇜
Ta phải tìm n
0
, c
1
c
2
sao cho
𝑐
n
3
𝑓󰇛𝑛󰇜23n
3
– 10 n
2
log
2
n
+ 7n + 6 𝑐
n
3
với n n
0
f(n) = (g(n)) c
1
, c
2
, n
0
>0 : n n
0
, c
1
g(n) f(n) c
2
g(n)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ví dụ 3: Chứng minh rằng f(n) = 23n
3
10 n
2
log
2
n + 7n + 6 𝚯󰇛𝑛
󰇜
f(n) = 23n
3
10 n
2
log
2
n + 7n + 6
f(n) = [23 – (10 log
2
n)/n + 7/n
2
+ 6/n
3
]n
3
Khi đó:
n 10 : f(n) (23 + 0 + 7/100 + 6/1000 )n
3
= (23 + 0 + 0.07 + 0.006)n
3
= 23.076 n
3
< 24 n
3
n 10 : f(n) (23 – log
2
10 + 0 + 0 )n
3
> (23 – log
2
16)n
3
=19n
3
Ta có:
n 10: 19 n
3
f(n) 24 n
3
(n
0
= 10, c
1
= 19, c
2
= 24, g(n) = n
3
)
Do đó: f(n) = (n
3
)
f(n) = (g(n)) c
1
, c
2
, n
0
>0 : n n
0
, c
1
g(n) f(n) c
2
g(n)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
O hiệu O lớn (big Oh)
Đối với hàm g(n) cho trước, ta ký hiệu O(g(n)) là tập các hàm
O(g(n)) = {f(n): tồn tại các hằng số dương c n
0
sao cho:
f(n) cg(n) với mọi n n
0
}
(tập tất cả các hàm tốc độ tăng nhỏ hơn hoặc bằng tộtăngcag(n)).
Ta nói: g(n) là cận trên tiệm cận của f(n), và viết f(n) = O(g(n)).
f(n) =O(g(n)) tức tồn tại hằng số c sao cho f(n) luôn cg(n) với mọi giá
trị n đủ lớn.
O(g(n)) là tập các hàm đạt tới giá trị cùng
không nhanh hơn g(n).
55
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Minh họa hình học
f(n) = 2n+6
Theo định nghĩa:
Cần tìm hàm g(n) và hằng số
c n
0
sao cho f(n) < cg(n)
khi n > n
0
g(n) = n, c = 4 và n
0
=3
f(n) là O(n)
g(n)=n
c g(n)=4n
n
f
(n) = 2n + 6
O(g(n))= {f(n): hằng số dương c n
0
, sao cho
n n
0
,
sao cho 0 f(n) cg(n)}
56
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ O lớn (Big-Oh)
dụ 1: Chứng minh rằng 2n + 10 = O(n)
f(n) = 2n+10, g(n) = n
Cần tìm hằng số c n
0
sao cho 2n +10 cn với mọi n n
0
(c 2) n 10
n 10/(c 2)
Chọn c = 3 và n
0
= 10
dụ 2: Chứng minh rằng 7n -2 = O(n)
f(n) = 7n-2, g(n) = n
Cần tìm hằng số c n
0
sao cho 7n - 2 cn với mọi n n
0
(7 c ) n ≤ 2
n ≤2/(7 c)
Chọn c = 7 và n
0
= 1
O(g(n))= {f(n): hằng số dương c n
0
, sao cho
n n
0
,
ta 0 f(n) cg(n)}
57
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Chú ý
Các giá trị của các hằng số dương n
0
c không phải duy nhất trong
chứng minh công thức tiệm cận
dụ: Chứng minh rằng 100n + 5 = O(n
2
)
100n + 5 ≤ 100n + n = 101n ≤ 101n
2
n ≥ 5
n
0
= 5 and c = 101
các hằng số cần tìm
100n + 5 ≤ 100n + 5n = 105n ≤ 105n
2
n ≥ 1
n
0
= 1 and c = 105
cũng các hằng số cần tìm
Chỉ cần tìm các hằng số dương c n
0
nào đó thỏa mãn bất đẳng thức trong
định nghĩa công thức tiệm cận
58
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ O lớn (Big-Oh)
dụ 3: Chứng minh rằng 3n
3
+ 20n
2
+ 5 = O(n
3
)
Cần tìm giá trị cho c n
0
sao cho 3n
3
+ 20n
2
+ 5 cn
3
với mọi n n
0
Bất đẳng thức đúng với c = 4 và n
0
= 21
dụ 4: Chứng minh rằng 3 log
2
n + 5 = O(log
2
n)
O(g(n))= {f(n): hằng số dương c n
0
, sao cho
n n
0
,
ta 0 f(n) cg(n)}
59
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ O lớn (Big-Oh)
dụ 5: hàm n
2
không thuộc O(n)
n
2
cn
n c
Bất đẳng thức trên không đúng
c phải hằng số
1
10
100
1,000
10,000
100,000
1,000,000
1 10 100 1,000
n
n^2
100n
10n
n
O(g(n))= {f(n): hằng số dương c n
0
, sao cho
n n
0
,
ta 0 f(n) cg(n)}
60
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
O lớn tốc độ tăng
hiệu O lớn cho cận trên tốc độ tăng của một hàm
Khi ta nói f(n) là O(g(n))” nghĩa tốc độ tăng của hàm f(n) không
lớn hơn tốc độ tăng của hàm g(n)
Ta có thể dùng hiệu O lớn để sắp xếp các hàm theo tốc độ tăng của
chúng
f(n) O(g(n)) g(n) O(f(n))
g(n) có tốc độ tăng lớn hơn f(n)
g(n) có tốc độ tăng nhỏ hơn f(n)
? ?
g(n) và f(n) cùng tốc độ tăng
??
61
Yes
No
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Các biểu thức sai
() (())
f
nOgn
() (())
f
nOgn
X
X
62
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ O lớn (Big-Oh)
f(n) = 50n
3
+ 20n + 4 là O(n
3
)
Cũng đúng khi nói f(n) O(n
3
+n)
Không hữu ích, vì n
3
tốc độ tăng lớn hơn rất nhiều so với n, khi
n lớn
Cũng đúng khi nói f(n) O(n
5
)
OK, nhưng g(n) nên tốc độ tăng càng gần với tốc độ tăng của
f(n) càng tốt, thì đánh giá thời gian tính mới giá trị
3log(n) + log (log (n)) = O( ? )
Quy tắc đơn giản: Bỏ qua các số hạng
số thấp hơn các hằng số
63
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Một số quy tắc O lớn
Nếu f(n) là đa thức bậc d:
thì f(n)= O(n
d
), tức là,
1. Bỏ qua các số hạng số thấp hơn d
2. Bỏ qua các hằng số
dụ: 3n
3
+ 20n
2
+ 5 = O(n
3
)
Nếu f(n) = O(n
k
) thì f(n) = O(n
p
) với p > k
dụ: 2n
2
= O(n
2
) thì 2n
2
= O(n
3
)
Khi đánh giá tiệm cận f(n) = O(g(n)), ta nên tìm hàm g(n) có tốc độ tăng càng chậm
càng tốt
Sử dụng lớp các hàm tốc độ tăng nhỏ nhất thể
dụ: Nói “2n = O(n)” tốt hơn nói “2n = O(n
2
)”
Sử dụng lớp các hàm đơn giản nhất thể
dụ: Nói “3n +5 = O(n)” thay nói “3n +5 = O(3n)”
d
d
2
210
na...nanaanf
64
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ O lớn
Tất cả các hàm sau đều O(n):
n, 3n, 61n + 5, 22n 5, …
Tất cả các hàm sau đều O(n
2
):
n
2
, 9 n
2
, 18 n
2
+ 4n 53, …
Tất cả các hàm sau đều O(n log n):
n(log n), 5n(log 99n), 18 + (4n 2)(log (5n + 3)), …
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ω- hiệu Omega
Đối với hàm g(n) cho trước, ta kí hiệu (g(n)) tập các hàm
(g(n)) = {f(n): tồn tại các hằng số dương c n
0
sao cho:
cg(n)
f(n) với mọi n n
0
}
(tập tất cả các hàm tốc độ tăng lớn hơn hoặc bằng tốc độ tăng của g(n)).
Ta nói: g(n) là cận dưới tiệm cận của hàm, và viết f(n) = (g(n)).
f(n) = (g(n)) nghĩa tồn tại hằng số c sao cho f(n) luôn cg(n)vigiátr
n đủ lớn.
(g(n)) tập các hàm đạt tới giá trị cùng không chậm hơn g(n)
f(n)=(g(n)) f(n)=(g(n))
(g(n))(g(n)).
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ hiệu Omega
dụ 1: Chứng minh rằng 5n
2
= (n)
Cần tìm c n
0
sao cho cn 5n
2
với n n
0
Bất đẳng thức đúng với c = 1 và n
0
= 1
Nhận xét:
Nếu f(n) = (n
k
) thì f(n) = (n
p
) với p < k.
Khi đánh giá tiệm cận f(n) = (g(n)), ta cần tìm hàm g(n) có tốc độ
tăng càng nhanh càng tốt
dụ 2: Chứng minh
𝑛 = (lg n)
(g(n))= {f(n): hằng số dương c n
0
, sao cho
n n
0
,
ta 0 cg(n) f(n)}
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
hiệu tiệm cận trong các đẳng thức
hiệu tiệm cận còn được dùng để thay thế các biểu thức chứa các toán
hạng với tốc độ tăng chậm.
dụ:
4n
3
+3n
2
+2n +1=4n
3
+3n
2
+ (n)
=4n
3
+ (n
2
)=(n
3
)
Trong các đẳng thức, (f(n)) thay thế cho một hàm nào đó g(n) (f(n))
Trong dụ trên, ta dùng (n
2
) thay thế cho 3n
2
+2n +1
68
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Các hiệu tiệm cận
Định : Đối với hai hàm bất kỳ f(n)vàg(n), ta có 𝑓 𝑛𝚯(g(n))
khi chỉ khi
𝑓
𝑛𝑂(g(n)) và 𝑓 𝑛(g(n))
Đồ thị minh họa cho các hiệu tiệm cận 𝚯, O,vàΩ
69
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 1: Chứng minh f(n) = 5n
2
𝚯󰇛𝑛
󰇜
Vì:
5n
2
O 𝑛
2
f(n) = O(g(n)) nếu tồn tại hằng số c > 0 và hằng số nguyên n
0
1 sao cho f(n) ≤
cg(n) với n n
0
chọn c = 5 và n
0
= 1
5n
2
Ω(n
2
)
f(n) = (g(n)) nếu tồn tại hằng số c > 0 và hằng số nguyên n
0
1 sao cho f(n)
cg(n) với n n
0
Chọn c = 5 và n
0
= 1
Do đó: f(n) = (n
2
)
Định lý: Đối với hai hàm bất kỳ f(n) và g(n), ta có
𝑛𝚯(g(n))
khi chỉ khi
𝑛𝑂(g(n))
𝑛(g(n))
f(n) = (g(n))
𝑛𝚯(g(n)) f(n) = O(g(n))
70
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 2: Chứng minh f(n) = 3n
2
–2n + 5 𝚯󰇛𝑛
󰇜
Vì:
3n
2
–2n + 5 O
𝑛
2
f(n) = O(g(n)) nếu tồn tại hằng số c > 0 và số nguyên n
0
1 sao cho
f(n) ≤ cg(n) với n n
0
Chọn c = ? và n
0
= ?
3n
2
–2n + 5 Ω(n
2
)
f(n) = (g(n)) nếu tồn tại hằng số c > 0 và số nguyên n
0
1 sao cho
f(n) cg(n) với n n
0
Chọn c = ? và n
0
= ?
Do đó: f(n) = (n
2
)
Định lý: Đối với hai hàm bất kỳ f(n) và g(n), ta có
𝑛𝚯(g(n))
khi chỉ khi
𝑛𝑂(g(n))
𝑛(g(n))
f(n) = (g(n))
𝑛𝚯(g(n)) f(n) = O(g(n))
71
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài tập 1
Chứng minh: 100n + 5 ≠ (n
2
)
Giải: Chứng minh bằng phản chứng
Giả sử:
100n + 5 = (n
2
)
c, n
0
sao cho: 0 cn
2
100n + 5
Ta có: 100n + 5 100n + 5n = 105n n 1
Do đó: cn
2
105n n(cn 105) 0
n > 0 cn 105 0 n 105/c
bất đẳng thức trên không đúng c phải hằng số
72
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài tập 2
Chứng minh: n (n
2
)
Giải: Chứng minh bằng phản chứng
Giả sử: n = (n
2
)
c
1
, c
2
, n
0
sao cho: c
1
n
2
n c
2
n
2
n n
0
n ≤ 1/c
1
Bất đẳng thức trên không đúng c
1
phải hằng số
73
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài tập 3:Chứng minh
a) 6n
3
(n
2
)
Giải: Chứng minh bằng phản chứng
Giả sử: 6n
3
= (n
2
)
c
1
, c
2
, n
0
sao cho: c
1
n
2
≤ 6n
3
c
2
n
2
n n
0
n c
2
/6 n n
0
Bất đẳng thức trên không đúng c
2
phải là hằng số
b) n (log
2
n)
Giải:
74
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Cách nói về thời gian tính
Nói “Thời gian tính O(f(n))”, hiểu đánh giá trong tình huống tồi nhất (worst
case) O(f(n))
(nghĩa là, không tồi hơn c*f(n)vin lớn, hiệu O lớn cho ta cận
trên). [Thường nói: “Đánh giá thời gian tính trong tình huống tồi nhất O(f(n))”]
Nghĩa thời gian tính trong tình huống tồi nhất được xác định bởi một hàm nào
đó g(n)(f(n))
Nói “Thời gian tính (f(n))”, hiểu
đánh giá trong tình huống tốt nhất (best
case)
(f(n)) (nghĩa là, không tốt hơn c*f(n)vin lớn, hiệu Omega cho ta
cận dưới). [Thường nói: “Đánh giá thời gian tính trong tình huống tốt nhất
(f(n))”]
Nghĩa thời gian tính trong tình huống tốt nhất được xác định bởi một hàm nào
đó g(n) (f(n))
75
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
76
Thời gian tính trong tình huống tồi nhất
Khi phân tích một thuật toán
Chỉ quan tâm đến các trường hợp thuật toán chạy
Tốn thời gian chạy nhất
(tính cận trên cho thời gian tính của thuật toán)
Nếu thuật toán thể giải trong thời gian cỡ hàm f(n)
Thì trường hợp tồi nhất, thời gian chạy không thể lớn hơn c*f(n)
Hữu ích khi thuật toán áp dụng cho trường hợp
Cần biết cận trên cho thuật toán
dụ:
Các thuật toán áp dụng chạy trong nhà máy điện hạt nhân.
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
77
Thời gian tính trong tình huống tốt nhất
Khi ta phân tích một thuật toán
Chỉ quan tâm đến các trường hợp thuật toán chạy
Ít thời gian nhất
(tính cận dưới của thời gian chạy)
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
78
Thời gian tính trong tình huống trung bình
Nếu thuật toán phải sử dụng nhiều lần
hữu ích khi tính đượng thời gian chạy trung bình của thuật toán với kích
thước dữ liệu đầu vào n
Đánh giá thời gian tính trung bình khó hơn với việc đánh giá thời gian tính
tồi/tốt nhất
Cần thông tin về phân phối của dữ liệu dữ liệu
dụ: Thuật toán sắp xếp chèn (Insertion sorting) có thời gian trung bìnhcn
2
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Một số lớp thuật toán bản
Hằng số O(1)
Logarithmic O(log
2
n)
Tuyến tính O(n)
N-Log-N O(nlog
2
n)
Bình phương (Quadratic) O(n
2
)
Bậc 3 (Cubic) O(n
3
)
Hàm (exponential) O(a
n
) (a > 1)
Đa thức (polynomial): O(n
k
) (k ≥1)
Thuật toán đánh giá thời gian tính O(n
k
) được gọi
thut toán
thi gian tính đathc
(hay vắn tắt: thut toán đathc)
Thuật toán đa thức được coi thuật toán hiệu quả.
Các thuật toán với thời gian tính hàm không hiệu quả.
Sau đây, ta sẽ lấy một số dụ về phân loại các hàm
79
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Một số hàm bản
Những hàm nào trong số những hàm sau
giống nhau hơn?
n
1000
n
2
2
n
80
Đa thức
(polynomial)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Một số hàm bản
Những hàm nào trong số những hàm sau
giống nhau hơn?
1000n
2
3n
2
2n
3
81
Hàm bậc 2
(quadratic)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Tốc độ tăng của một số hàm bản
n lognn nlognn
2
n
3
2
n
4 2 4 8 16 64 16
8 3 8 24 64 512 256
16 4 16 64 256 4,096 65,536
32 5 32 160 1,024 32,768 4,294,967,296
64 6 64 384 4,094 262,144 1.84 * 10
19
128 7 128 896 16,384 2,097,152 3.40 * 10
38
256 8 256 2,048 65,536 16,777,216 1.15 * 10
77
512 9 512 4,608 262,144 134,217,728 1.34 * 10
154
1024 10 1,024 10,240 1,048,576 1,073,741,824 1.79 * 10
308
82
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
83
Phân loại thời gian tính của thuật toán
Thời gian để giải một bộ dữ liệu đầu vào của
Thuật toán thời gian tính tuyến tính (Linear Algorithm):
Không bao giờ lớn hơn c*n
Thuật toán thời gian tính hàm đa thức bậc 2 (Quadratic Algorithm):
Không bao giờ lớn hơn c*n
2
Thuật toán thời gian tính hàm đa thức bậc ba (Cubic Algorithm):
Không bao giờ lớn hơn c*n
3
Thuật toán thời gian tính đa thức (Polynomial Algorithm)
Không bao giờ lớn hơn n
k
Thuật toán thời gian tính hàm (Exponential Algorithm)
Không bao giờ lớn hơn c
n
với c k các hằng số tương ứng
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Cận trên cận dưới
Upper Bound and Lower Bound
Định nghĩa (Upper Bound). Cho bài toán P, ta nói cận trên cho thời gian
tính của P O(g(n)) nếu để giải P tồn tại thuật toán giải với thời gian tính
O(g(n)) .
Định nghĩa (Lower Bound). Cho bài toán P, ta nói cận dưới cho thời gian
tính của P
(g(n)) nếu mọi thuật toán giải P đucóthigiantínhlà
(g(n)) .
Định nghĩa. Cho bài toán P, ta nói thời gian tính của P
(g(n)) nếu P
cận trên O(g(n)) cận dưới (g(n)) .
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài toán d
giải, khó giải
không giải được
Một bài toán được gọi d gii (tractable) nếu như thể giải được nhờ thuật
toán đa thức. Bài toán cận trên cho thời gian tính là đa thức.
d: bài toán dãy con lớn nhất, bài toán sắp xếp dãy n số, ....
Một bài toán được gọi
khó gii (intractable) nếu như không thể giải được bởi
thuật toán đa thức. Bài toán cận dưới cho thời gian tính hàm mũ.
d: Bài toán liệt các hoán vị của n số, các xâu nhị phân độ dài n, ...
Một dạng bài toán nữa cũng được
coi khó gii: Đó những bài toán cho đến thời
điểm hiện tại vẫn chưa tìm được thuật toán đa thức để giải nó.
d: Bài toán cái túi, Bài toán người du lịch,…
Một bài toán được gọi
không gii được (nonsolvable) nếu n không tồn tại thuật
toán để giải nó..
d: Bài toán về tính dừng, Bài toán về nghiệm nguyên của đa thức
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Sự tương tự giữa so sánh các hàm số so sánh số
Chú ý rằng mối quan hệ giữa các hàm số cũng giống như mỗi quan hệ
“<, >, =” giữa các số
f g a b
f (n) = O(g(n)) a b
f (n) = (g(n)) a b
f (n) = (g(n)) a = b
f (n) = o(g(n)) a < b
f (n) =

(g(n)) a > b
86
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Hàm mũ:
a
(b+c)
= a
b
a
c
a
bc
= (a
b
)
c
a
b
/a
c
= a
(b-c)
b = a
log
a
b
b
c
= a
c*log
a
b
Hàm Logarit:
Nhắc lại một số khái niệm toán học
x = log
b
a số
cho a = b
x
.
Logarit tự nhiên: ln a = log
e
a
Logarit bậc 2: lg a = log
2
a
lg
2
a = (lg a)
2
lg lg a =lg(lga)
ac
a
b
bb
c
c
b
b
n
b
ccc
a
bb
b
ca
b
a
aa
b
a
a
ana
baab
ba
loglog
log
log
1
log
log)/1(log
log
log
log
loglog
loglog)(log
87
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Hàm logarit hàm
Nếu số của hàm logarit thay đổi giá trị từ hằng số này sang
hằng số khác, thì giá trị của hàm bị thay đổi một lượng hằng số.
dụ: log
10
n *
log
2
10 = log
2
n.
Do đó, trong hiệu tiệm cận số của log là không quan trọng:
O(lg n) = O(ln n) = O(log n)
Giá trị của hai hàm khác nhau số khác nhau một lượng cỡ
hàm (chứ không phải một lượng hằng số)
dụ: 2
n
=
(2/3)
n
*3
n
.
88
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài tập
Sắp xếp các hàm sau theo thứ tự tốc độ tăng dần
1. nlog
2
n
2. log
2
n
3
3. n
2
4. n
2/5
5.
𝟐
𝒍𝒐𝒈
𝟐
𝒏
6. log
2
(log
2
n)
7. Sqr(log
2
n)
89
Sqr:square(bình phương)
Sqrt:squareroot(căn bậc 2)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Cách nhớ các hiệu
Theta
f(n) = (g(n))
f(n) ≈ cg(n)
Big Oh
f(n) = O(g(n)) f(n) ≤ cg(n)
Big Omega
f(n) = Ω(g(n)) f(n) ≥ cg(n)
90
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Các tính chất
Transitivity (truyền ứng)
f(n) = (g(n)) & g(n) = (h(n)) f(n) = (h(n))
f(n) = O(g(n)) & g(n) = O(h(n)) f(n) = O(h(n))
f(n) = (g(n)) & g(n) = (h(n)) f(n) = (h(n))
Reflexivity (phản xạ)
f(n) = (f(n)) f(n) = O(g(n)) f(n) = (g(n))
Symmetry (đối xứng)
f(n) = (g(n)) if and only if g(n) = (f(n))
Transpose Symmetry (Đối xứng chuyển vị)
f(n) = O(g(n)) if and only if g(n) = (f(n))
dụ: A = 5n
2
+ 100n, B= 3n
2
+ 2 . Chứng minh A (B)
Giải: A (n
2
), n
2
(B) A (B)
91
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Liên hệ với khái niệm giới hạn
lim [f(n) / g(n)] < f(n) O(g(n))
n

0 < lim [f(n) / g(n)] < f(n) (g(n))
n

0 < lim [f(n) / g(n)] f(n) (g(n))
n

lim [f(n) / g(n)] không xác định không thể nói
n

Chú ý: f(n) = n sin n; g(n) = n. Mặc không tồn
tại, nhưng ràng n sin n = O(n).
dụ: Biểu diễn hàm A bằng hiệu tiệm cận sử dụng hàm B.
AB
log
3
(n
2
) log
2
(n
3
)
log
b
a =log
c
a/log
c
b;A=2lgn /lg3,B=3lgn,A/B=2/(3lg3) A (B)
A(B)
92
()
lim limsin
()
nn
fn
n
gn
 
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài tập
Chứng minh
1) 3n
2
100n + 6 = O(n
2
)
2) 3n
2
100n + 6 = O(n
3
)
3) 3n
2
100n + 6 ≠ O(n)
4) 3n
2
100n + 6 = (n
2
)
5) 3n
2
100n + 6 ≠ (n
3
)
6) 3n
2
100n + 6 = (n)
7) 3n
2
100n + 6 = 𝚯(n
2
)
8) 3n
2
100n + 6 ≠ 𝚯(n
3
)
9) 3n
2
100n + 6 ≠ 𝚯(n)
93
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Chú ý
Giả sử 2 thuật toán:
Thuật toán A thời gian chạy 30000n
Thuật toán B có thời gian chạy 3n
2
Theo đánh giá tiệm cận, thuật toán A tốt hơn thuật
toán B
Tuy nhiên, nếu kích thước dữ liệu của bài toán luôn
nhỏ hơn 10000, thì thuật toán B lại tốt (nhanh) hơn A
B
A
Kích thước
dữ liệu
đầu vào
Thời gian chạy
10000
94
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ni dung
1.1. dụ mở đầu
1.2. Thuật toán độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số thuật phân tích thuật toán
1.6. Giải công thức đệ quy
95
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.4. Giả ngôn ngữ (Pseudocode)
Để tả thuật toán, ta có thể sử dụng
một ngôn ngữ lập trình nào đó. Tuy
nhiên, điều đó thể làm cho việc tả
thuật toán trở nên phức tạp khó nắm
bắt. Do đó, để tả thuật toán, người ta
thường sử dụng giả ngôn ngữ (pseudo
language), cho phép:
tả thuật toán bằng ngôn ngữ đời
thường
Sử dụng các cấu trúc câu lệnh tương
tự như của ngôn ngữ lập trình.
Dưới đây ta liệt một số câu lệnh
chính được sử dụng trong giáo trình để
tả thuật toán.
d: tìm phnt lnnht trong mng
Function arrayMax(A,n)
//Input: mảng A gồm n số nguyên
//Output: phần tử lớn nhất của mảng A
begin
currentMax A[0]
for i 1to n 1
if (A[i] currentMax) then
currentMax A[i]
endif;
endfor;
return
currentMax;
end;
96
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.4. Pseudocode
Khai báo biến
integerx,y;
realu,v;
boolean a,b;
charc,d;
datatype x;
Lệnh gán
x=biểu thức;
hoặc
x←biểu thức;
dụ: x ← 1+4; y=a*y+2;
97
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.4. Pseudocode
Cấu trúc điều khiển:
if điều_kiện then
y các câu lệnh
else
y các câu lệnh
endif;
while điều_kiện do
dãy các câu lệnh
endwhile;
repeat
dãy các câu lệnh
until condition;
98
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.4. Pseudocode
Cấu trúc điều khiển:
for i=n1to n2[stepd]
dãy các câu lệnh
endfor;
Case
điu_kin_1: câu_lnh_1;
điu_kin_2: câu_lnh_2;
.
.
.
điu_kin_n: câu_lnh_n;
endcase;
99
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.4. Pseudocode
Vào/ra:
read(X); /* X là biến */
print(data);
hoặc
print(thông báo);
Hàm thủ tục:
Function name(arguments)
begin
khai báo biến;
các câu lệnh trong hàm;
return (value);
end;
Procedure
name(arguments)
begin
khai báo biến;
các câu lệnh trong thủ tục;
end;
100
d: tìm phnt lnnht trong mng
Function arrayMax(A,n)
//Input: mảng A gồm n số nguyên
//Output: phần tử lớn nhất của mảng A
begin
currentMax A[0]
for i 1to n 1
if (A[i] currentMax) then
currentMax A[i]
endif;
endfor;
return
currentMax;
end;
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.4. Pseudocode
Procedure swap(x,y)
begin
temp=x;
x=y;
y=temp;
end;
d 2: hoán đigiátr cahaibiến
Hoặc thể viết đơn giản như sau:
Procedure swap(x,y)
temp=x;
x=y;
y=temp;
101
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Pseudocode: Ví dụ 3
Đề bài: Tìm số nguyên tố nhỏ nhất lớn hơn một số nguyên dương n cho trước
Đầu tiên ta viết hàm
Is_Prime kiểm tra xem một s nguyên dương m phải số
nguyên tố hay không. Xây dựng hàm này như sau:
Nếu m = a*b với 1 < a, b < m, thì một trong hai số a b giá trị không thể
vượt quá
𝑚. Do đó, số nguyên tố lớn nhất nhỏ hơn m sẽ giá trị không vượt
quá
𝑚 m số nguyên tố nếu không chia hết cho bất số nguyên nào
trong khoảng [2,
𝑚].
Sau đó, để tìm số nguyên tố nhỏ nhất lớn hơn n như sau:
Ta dùng hàm
Is_Prime để xét lần lượt các số lớn hơn n là: n+1, n+2, n+3,…
xem số nào số nguyên tố hay không. Nếu tìm được thì thuật toán kết thúc
trả về số nguyên tố vừa tìm được.
102
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Pseudocode: Ví dụ 3
Thuật toán kiểm tra số nguyên dương phải số nguyên tố hay không:
Input: Số nguyên dương m.
Output: true nếu m số nguyên tố, false nếu ngược lại.
Function Is_prime(m)
begin
i = 2;
while (i*i <= m) and (m mod i 0) do
i=i+1;
endwhile;
Is_prime = i > sqrt(m);
end Is_Prime;
Thuật toán tìm số nguyên tố nhỏ nhất lớn hơn số nguyên dương n:
Thuật toán sử dụng hàm Is_prime như 1 thủ tục con.
Input: Số nguyên dương n.
Output: m số nguyên tố nhỏ nhất lớn hơn số nguyên dương n.
procedure Lagre_Prime(n)
begin
m = n+1;
while not Is_prime(m) do
m=m+1;
endwhile;
end;
103
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ni dung
1.1. dụ mở đầu
1.2. Thuật toán độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số thuật phân tích thuật toán
1.6. Giải công thức đệ quy
104
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Tính toán thời gian tính của thuật toán
Đánh giá qua thời gian chạy thực nghiệm:
Cần: cài đặt chương trình thực thi thuật toán, sau đó chạy chương trình đothi
gian chạy.
Nhược điểm:
Bắc buộc phải cài đặt thuật toán
Kết quả thu được sẽ không bao gồm thời gian chạy của những dữ liệu đầu vào không
được chạy thực nghiệm. Do vậy, cần chọn được các bộ dữ liệu thử đặc trưng cho tất
cả tập các dữ liệu vào của thuật toán rất khó khăn và tốn nhiều chi phí.
Để so sánh thời gian tính của hai thuật toán, cần phải chạy thực nghiệm hai thuật
toán trên cùng một máy, và sử dụng cùng một phần mềm.
Ta cần đánh giá thuật toán theo hướng xấp xỉ tiệm cận
Đánh giá thời gian chạy theo hướng xấp xỉ tiệm cận:
Sử dụng giả ngôn ngữ để tả thuật toán, thay cài đặt thực sự
Phân tích thời gian tính như làm hàm của dữ liệu đầu vào, n
Đánh giá trên tất cả các bộ dữ liệu vào thể của bài toán
Cho phép ta đánh giá được thời gian tính của thuật toán độc lập với phần cứng
phần mềm cần sử dụng để cài đặt thuật toán.
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Phép toán bản
Để đo thời gian tính bằng phương pháp đánh giá tiệm cận, ta sẽ đếm
số phép toán bản thuật toán phải thực hiện
phép toán thể thực hiện với thời gian bị chặn bở một hằng số
không phụ thuộc vào kích thước dữ liệu vào.
dụ về các phép toán bản:
Tính biểu thức
x
2
+e
y
Phép gán giá trị cho một biến cnt cnt+1
Đánh chỉ số mảng A[5]
Gọi 1 phương thức mySort(A,n)
Lệnh trả về giá trị từ 1 phương thức return(cnt)
106
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Phân tích độ phức tạp của thuật toán: Các thuật bản
1. Cấu trúc tuần tự
Thi gian tính cachương trình P; Q”,với P Q là hai đoạn chương trình thực thi
một thuật toán, P thực hiện trước, rồi đến Q là
Time(P; Q) = Time(P) + Time(Q) ,
hoặc ta có thể dùng hiệu tiệm cận theta:
Time(P; Q) = (max(Time(P), Time(Q)).
với Time(P), Time(Q) là thời gian tính của P Q.
2. Vòng lặp FOR
for i=1to m do P(i);
Giả sử thời gian thực hiện P(i) là t(i), khi đó thời gian thực hiện vòng lặp for là
𝑡󰇛𝑖󰇜

3. Vòng lặp lồng nhau
for i=1to n do
for j =1 to m do P(j);
Giả sử thời gian thực hiện P(j) là t(j), khi đó thời gian thực hiện vòng lặp lồng nhau này
là:
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Phân tích độ phức tạp của thuật toán: Các thuật bản
4. If/Else
if
(điều_kiện) then P;
else Q;
endif;
Thời gian thực hiện câu lệnh if/else
= thời gian kiểm tra (điều_kiện) + max (Time(P), Time (Q))
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ
Case1: for (i=0; i<n; i++)
for (j=0; j<n; j++)
k++;
Case 2: for (i=0; i<n; i++)
k++;
for (i=0; i<n; i++)
for (j=0; j<n; j++)
k++;
Case 3: for (int i=0; i<n-1; i++)
for (int j=0; j<i; j++)
int k+=1;
O(n
2
)
O(n
2
)
O(n
2
)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Phân tích độ phức tạp của thuật toán: Các thuật bản
5. Vòng lặp while/repeat
Cần xác định một hàm của các biến trong vòng lặp sao cho hàm này có giá
trị giảm dần trong quá trình lặp. Khi đó:
Để chứng minh tính kết thúc của vòng lặp ta chỉ cần chỉ ra giá trị của
hàm là số nguyên dương.
Còn để xác định số lần lặp ta cần phải khảo sát xem giá trị của hàm giảm
như thế nào.
Việc phân tích vòng lặp Repeat được tiến hành tương tự như phân tích vòng
lặp While.
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Câu lệnh đặc trưng
Định nghĩa. Câu lnh đặctrưng câu lnh đượcthchin
thường xuyên ít nhtlàcũng như btk câu lnh nào trong
thut toán.
Nếugiảthiếtthigianthchinmicâulnhlàbịchnbi
hằng số thì thời gian tính của thuật toán sẽ cùng cỡ với số
lần thực hiện câu lệnh đặc trưng
=> Để đánh giá thời gian tính thể đếm số lần thực hiện
câu lệnh đặc trưng
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
112
dụ 1: Tính dãy Fibonacci
Dãy Fibonacci (0, 1, 1, 2, 3,
5, 8, 13, 21, 34….)
f
0
=0;
f
1
=1;
f
n
= f
n-1
+ f
n-2
function Fibrec(n)
if n <2 then return n;
else return Fibrec(n-1)+Fibrec(n-2);
function Fibiter(n)
i=0;
j=1;
for k=1 to n do
j=i + j;
i=j – i;
return j;
n 10 20 30 50 100
Fibrec
8ms 1sec 2min 21days 10
9
years
Fibiter
0.17ms 0.33ms 0.5ms 0.75ms 1.5ms
Câu lệnh đặc trưng
Số lần thực hiện câu lệnh đặc trưng n Thời gian chạy
Fibiter O(n)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 2: Bài toán dãy con lớn nhất
Cho mảng số nguyên A
1
, A
2
, …, A
N
, tìm giá trị lớn nhất của
𝐴

NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Thuật toán 1. Duyệt toàn bộ (Brute force)
Chọn câu lệnh đặc trưng sum+=a[k]
Thời gian tính của thuật toán: O(n
3
)
int maxSum = 0;
for (int i=0; i<n; i++) {
for (int j=i; j<n; j++) {
int sum = 0;
for (int k=i; k<=j; k++)
sum += a[k];
if (sum > maxSum)
maxSum = sum;
}
}
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Thuật toán 2. Duyệt toàn bộ cải tiến
O(n
2
)
int maxSum = a[0];
for (int i=0; i<n; i++) {
int sum = 0;
for (int j=i; j<n; j++) {
sum += a[j];
if (sum > maxSum)
maxSum = sum;
}
}
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Thuật toán 3. Đệ quy
116
O(n)
O(n)
T(n/2)
T(n/2)
T(n) = 2T(n/2)+O(n)
T(n) = O(nlogn)
Giải công thức đệ quy này thế
nào ?(xem mục 1.6.)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Nhắc lại một số kiến thức
Tổng bình phương:
Tổng mũ:
Dãy:
Trường hợp đặc biệt A = 2
2
0
+ 2
1
+ 2
2
+ … + 2
N
= 2
N+1
-1
N largefor
36
)12)(1(
3
1
2
NNNN
i
N
i
-1k and N largefor
|1|
1
1
k
N
i
k
N
i
k
1
1
1
0
A
A
A
N
N
i
i
N
i
NNiNNS
1
2/)1(21)(
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 3
Đưa ra đánh giá tiệm cận O lớn cho thời gian tính T(n) của
đoạn chương trình sau:
for (int i = 1; i<=n; i++)
for (int j = 1; j<= i*i*i; j++)
for (int k = 1; k<=n; k++)
x = x + 1;
Giải:
So T(n) = O(n
5
).








3
33
111
3
11 1 1 1
3345
11 1
() 1
( 1)
1
ni n
ijk
ni n i n
ij i j i
nn n
ii i
Tn
nn ni
ni nn n n
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 4
Đưa ra đánh giá tiệm cận O lớn cho thời gian tính T(n) của đoạn chương trình
sau:
a) int x = 0;
for (int i = 1; i <=n; i *= 2)
x=x+1;
Giải:
Vòng lặp for thực hiện log
2
n lần, do đó T(n) = O(log
2
n).
b) int x = 0;
for (int i = n; i > 0; i /= 2)
x=x+1;
Giải:
Vòng lặp for thực hiện …..
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 5
Đưa ra đánh giá tiệm cận O lớn cho thời gian tính T(n) của đoạn chương trình
sau:
int n;
if (n<1000)
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
for (int k=0; k<n; k++)
cout << "Hello\n";
else
for (int j=0; j<n; j++)
for (int k=0; k<n; k++)
cout << "world!\n";
Giải:
T(n) hằng số khi n <1000. T(n) = O(n
2
).
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 6: Thuật toán số nguyên tố
Thuật toán kiểm tra xem số nguyên dương m > 1 có phải
số nguyên tố hay không.
Algorithm PRIME(m)
for i=2 to sqrt(m) do
if m mod i = 0 then return FALSE
return YES
Thời gian tính: T(n) = O( ). Thuật toán đa thức?
Kích thước dữ liệu vào: n log
2
m 2
n
T(n) = O(m
1/2
) = O(2
n/2
).
Thời gian tính hàm !
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Ni dung
1.1. dụ mở đầu
1.2. Thuật toán độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số thuật phân tích thuật toán
1.6. Giải công thức đệ quy
Độ phức tạp tính toán của các thuật toán được xây dựng dưới dạng công thức đệ
quy của số lượng thao tác trong thuật toán.
dụ: Trong mục trước, ta học thuật toán đệ quy giải bài toán tổng dãy con lớn
nhất độ phức tạp T(n) = 2T(n/2) + O(n).
Giải công thức đệ quy này ta thu được T(n) = O(nlogn)
122
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy
Định nghĩa:
Công thức đệ quy cho dãy số {a
n
} là công thức biểu diễn a
n
dưới dạng
một hoặc nhiều thành phần trước trong dãy a
0
, a
1
, …, a
n-1
với mọi số
nguyên n
n
0
, n
0
số nguyên không âm
Một dãy số được gọi một
lời giải của công thức đệ quy nếu các thành phần
trong dãy số đó thỏa mãn công thức đệ quy.
dụ: Xét công thức đệ quy
a
n
= 2a
n-1
a
n-2
với n = 2, 3, 4, …
Dãy số a
n
=3n lời giải của công thức đệ quy đã cho?
Với n 2 ta có:
2a
n-1
a
n-2
= 2(3(n –1)) –3(n –2) = 3n = a
n
Do đó, dãy số a
n
=3n lời giải của công thức đệ quy đã cho
Dãy số a
n
=5 cũng lời giải của công thức đệ quy này?
Với n 2 ta có: 2a
n-1
a
n-2
= 25 - 5 = 5 = a
n
Do đó, dãy a
n
=5 cũng lời giải của công thức đệ quy đã cho
Cùng 1 công thức đệ quy thể nhiều lời giải. Tại sao???
Dãy số a
n
=n+1??
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Một công thức đệ quy không các giá trị đầu (các điều kiện đầu).
thể (thường có)
nhiều lời giải
d: a
n
= 2a
n-1
a
n-2
với n = 2, 3, 4,... Công thức đệ quy này các lời giải:
a
n
=5
a
n
=3n
a
n
=n+1
Nếu
cả công thức đệ quy các điều kiện đầu đều được xác định, thì dãy số lời
giải của công thức đệ quy sẽ được xác định
duy nhất.
d: a
n
= 2a
n-1
a
n-2
với n = 2, 3, 4,..
với a
0
=0; a
1
= 3
Dãy số a
n
=5 không phải lời giải
Dãy số a
n
=3n lời giải duy nhất
Công thức đệ quy công thức cho phép tính giá trị của các đại
lượng theo từng bước, dựa vào các giá trị tính ở các bước trước
một số giá trị đầu.
1.6. Giải công thức đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy
Ta hiểu việc giải công thức đệ qui việc tìm công thức dưới dạng hiện cho
số hạng tổng quát của dãy số thoả mãn công thức đệ qui đã cho.
dụ: Cho công thức đệ quy:
a
n
= 2a
n-1
a
n-2
với n = 2, 3, 4,…
a
0
=0; a
1
= 3
Công thức dạng hiện của công thức đệ quy trên dãy số a
n
=3n
a
n
=3n được gọi nghiệm (lời giải) của công thức đệ quy trên
Chưa phương pháp giải mọi công thức đệ quy.
Xét một số phương pháp giải:
Phương trình đặc trưng giải Công thức đệ quy tuyến tính thuần nhất hệ số hằng
(sẽ viết tắt CTĐQ TTTNHSH)
Phương pháp thế xuôi
Phương pháp thế ngược
Cây đệ quy
125
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy: Phương pháp Phương trình đặc trưng
Định nghĩa. Công thc đệ qui tuyến tính thunnhth s hng bck công thức đệ qui sau
a
n
= c
1
a
n−1
+ … + c
k
a
nk
trong đó c
i
các hằng số, và c
k
≠ 0.
Giải thích:
Tuyến tính: vế phải tổng của các số hạng trước số hạng an trong dãy số với các hệ số (c
1
,
c
2
, ..,c
k
) là hằng số (không phải hàm phụ thuộc vào n)
Thuần nhất: vế phải không thêm số hạng nào khác với các số hạng a
j
của dãy
Bậc k: vế phải số hạng thứ (n-k) của dãy
Dãy số thoả mãn công thức đã cho xác định duy nhất nếu đòi hỏi thoả mãn k điều kiện
đầu: a
0
=C
0
,a
1
=C
1
, ..., a
k-1
=C
k-1
,
trong đó C
0
, C
1
, ..., C
k-1
các hằng số.
dụ 1: a
n
= 2a
n-1
a
n-2
với n = 2, 3, 4,... Công thức đệ quy này một số lời giải như sau:
a
n
=5 a
n
=3na
n
=n+1
dụ 2: a
n
= 2a
n-1
a
n-2
với n = 2, 3, 4,… và các điều kiện đầu: a
0
=0; a
1
= 3
Dãy a
n
=5 không lời giải của công thức đệ quy đã cho
Dãy a
n
=3n lời giải của công thức đệ quy đã cho
126
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ1: Đâu CTĐQ TTTNHSH
1) a
n
= 4a
n-1
+2na
n-3
2) h
n
= 2h
n-1
+ 1
3) b
n
= 5b
n-2
+ 2(b
n-3
)
2
4) q
n
= 3 q
n-6
+ q
n-8
127
Công thức đệ quy tuyến tính thuần nhất hệ số hằng
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
128
dụ 2:
Công thức đệ quy P
n
= (1.05)P
n-1
công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 1.
Công thức đệ quy f
n
= f
n-1
+ f
n-2
công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 2.
Công thức đệ quy a
n
= a
n-5
công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 5.
CTĐQ TTTNHSH bậc k
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
Ta sẽ tìm nghiệm dưới dạng a
n
= r
n
, trong đó r hằng số.
Dãy số {
a
n
= r
n
} thoả mãn CTĐQ đã cho
a
n
= c
1
a
n−1
+ … + c
k
a
nk
nếu r thoả mãn phương trình:
r
n
= c
1
r
n−1
+ … + c
k
r
nk
, hay
r
k
c
1
r
k−1
− … − c
k
= 0
phương trình đặctrưng, còn nghimcanósẽ được gọi nghim đặc
trưng của CTĐQ TTTNHSH.
Ta thể sử dụng nghiệm đặc trưng để thu được công thức cho dãy số.
(chuyển vế
× với r
kn
)
129
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
Xét công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 2:
a
n
= c
1
a
n−1
+ c
2
a
n−2
Định 1
. Cho c
1
, c
2
các hằng số thực.
Giả sử phương trình r
2
-c
1
r-c
2
= 0 2 nghim phân bitr
1
r
2
.Khi
đó dãy s {a
n
} nghiệm của công thức đệ quy
a
n
= c
1
a
n-1
+ c
2
a
n-2
khi ch khi
a
n
=
1
(r
1
)
n
+
2
(r
2
)
n
(1)
n = 0, 1, ..., trong đó
1
,
2
các hng s.
130
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
Chứng minh. Trước hết ta chứng minh rằng nếu r
1
r
2
hai
nghiệm phân biệt của phương trình đặc trưng,
1
,
2
các hằng
số, thì dãy số
{a
n
} xác định bởi công thức (1) nghiệm của công
thức đệ quy đã cho
Thực vậy, do r
1
r
2
nghiệm đặc trưng nên
r
1
2
= c
1
r
1
+ c
2
,
r
2
2
= c
1
r
2
+ c
2
131
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
Từ đó suy ra
c
1
a
n-1
+ c
2
a
n-2
= c
1
(
1
r
1
n-1
+
2
r
2
n-1
) + c
2
(
1
r
1
n-2
+
2
r
2
n-2
)
=
1
r
1
n-2
(c
1
r
1
+ c
2
) +
2
r
2
n-2
(c
1
r
2
+ c
2
)
=
1
r
1
n-2
r
1
2
+
2
r
2
n-2
r
2
2
=
1
r
1
n
+
2
r
2
n
= a
n
.
132
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
Bây giờ ta sẽ chỉ ra rằng nghiệm {a
n
} của công thức đệ quy
a
n
=c
1
a
n-1
+c
2
a
n-2
luôn dạng (1) với
1
,
2
nào đó.
Thực vậy, giả sử {a
n
} nghiệm của công thức đệ quy đã cho với điều
kiện đầu
a
0
=C
0
,a
1
=C
1
,(2)
Ta chỉ ra rằng có thể tìm được các số
1
,
2
để cho (1) nghiệm của
hệ thức với điều kiện đầu này
133
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
Ta có
a
0
= C
0
=
1
+
2
,
a
1
= C
1
=
1
r
1
+
2
r
2
.
Hệ phương trình tuyến tính phụ thuộc hai ẩn
1
,
2
nàycóđnhthclàr
2
- r
1
0 (do r
1
r
2
) nghiệm duy nhất
1
= (C
1
-C
0
r
2
)/(r
1
-r
2
),
2
= (C
0
r
1
-C
1
)/(r
1
-r
2
).
Với những giá trị của
1
,
2
vừa tìm được, dãy {a
n
} xác định theo (1)
nghiệm của hệ thức đã cho với điều kiện đầu (2). Do hệ thức đã cho cùng với
điều kiện đầu (2) xác định duy nhất một dãy số, nên nghiệm của hệ thức
được cho bởi công thức (1).
Định được chứng minh
134
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
dụ 1: Tìm lời giải cho công thức đệ quy
a
n
= a
n-1
+ 2a
n-2
với a
0
= 2 và a
1
= 7 ?
Giải: Phương trình đặc trưng của công thức đệ quy
r
2
r 2 = 0.
2 nghiệm phân biệt r
1
= 2 và r
2
= -1.
Do đó, dãy {a
n
} là lời giải của công thức đệ quy khi chỉ khi:
a
n
=
1
2
n
+
2
(-1)
n
với giá trị nào đó của
1
2
.
Cho biểu thức a
n
=
1
2
n
+
2
(-1)
n
các điều kiện đầu a
0
= 2 và a
1
= 7, ta có
a
0
= 2 =
1
+
2
a
1
= 7 =
1
2 +
2
(-1)
Giả hệ phương trình này ta có:
1
= 3 và
2
= -1.
Do đó, lời giải của công thức đệ quy với ddieuf kiện đầu đã cho dãy {a
n
} với
a
n
= 32
n
(-1)
n
135
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Giải CTĐQ TTTNHSH
dụ 2: Tìm lời giải cho công thức đệ quy (dãy Fibonacci)
F
n
= F
n-1
+ F
n-2
, n 2,
F
0
= 0, F
1
= 1
Giả: Phương trình đặc trưng của công thức đệ quy
r
2
r –1 = 0.
2 nghiệm phân biệt
136
Leonardo Fibonacci
1170-1250
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Trường hợp nghiệm kép
Định 2: Cho c
1
, c
2
các hằng số thực, c
2
0. Giả sử phương
trình r
2
-c
1
r-c
2
= 0cónghimképr
0
. Khi đó dãy số {a
n
}là
nghiệm của công thức đệ qui a
n
=c
1
a
n-1
+c
2
a
n-2
khi ch khi
n = 0, 1, ..., trong đó
1
,
2
các hng s.
ar nr
n
nn


10 2 0
137
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 3
Tìm nghiệm cho công thức đệ quy
a
n
= 6 a
n-1
- 9 a
n-2
với điều kiện đầu a
0
= 1 và a
1
= 6.
Giải:
Phương trình đặc trưng:
r
2
-6r + 9 = 0 nghiệm kép r = 3. Do đó nghiệm của hệ thức dạng:
a
n
=
1
3
n
+
2
n 3
n
.
Để tìm
1
,
2
, sử dụng điều kiện đầu ta có
a
0
= 1 =
1
,
a
1
= 6 =
1
. 3 +
2
.1. 3
Giải hệ này ta tìm được
1
= 1 và
2
= 1.
Từ đó nghiệm của hệ thức đã cho là:
a
n
= 3
n
+ n 3
n
.
CTĐQ: a
n
= c
1
a
n−1
+ … + c
k
a
nk
Phương trình đặctrưng: r
k
c
1
r
k−1
− … − c
k
= 0
138
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Trường hợp tổng quát
Định 3. Cho c
1
,c
2
, ..., c
k
các số thực, c
k
 0. Giả sử phương trình
đặc trưng:
r
k
-c
1
r
k-1
-c
2
r
k-2
-...-c
k
= 0
k nghiệm phân biệt r
1
,r
2
, ..., r
k
.Khiđó dãy s {a
n
} nghimca
công thc:
a
n
=c
1
a
n-1
+c
2
a
n-2
+...+ c
k
a
n-k
,
khi ch khi
a
n
=
1
r
1
n
+
2
r
2
n
+...+
k
r
k
n
vin=0, 1, 2,..., trong đó
1
,
2
, ...,
k
các hng s
139
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 4
Tìm nghiệm của công thức đệ quy
a
n
= 6 a
n-1
- 11 a
n-2
+ 6 a
n-3
với điều kiện đầu
a
0
= 2, a
1
= 5, a
2
= 15.
Giải: Phương trình đặc trưng
r
3
-6r
2
+ 11 r -6 = 0
3 nghiệm r
1
= 1, r
2
= 2, r
3
= 3.
vậy, nghiệm dạng
a
n
=
1
1
n
+
2
2
n
+
3
3
n
.
CTĐQ: a
n
= c
1
a
n−1
+ … + c
k
a
nk
Phương trình đặc trưng: r
k
c
1
r
k−1
− … − c
k
= 0
140
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 4
Sử dụng các điều kiện đầu ta có hệ phương trình sau đây để xác
định các hằng số
1
,
2
,
3
:
a
0
= 2 =
1
+
2
+
3
a
1
= 5 =
1
+
2
.2 +
3
.3
a
2
= 15 =
1
+
2
.4 +
3
.9.
Giải hệ phương trình trên ta thu được
1
= 1,
2
= -1 vμ
3
= 2.
Vậy nghiệm của công thức đã cho
a
n
= 1 - 2
n
+ 2. 3
n
141
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Trường hợp tổng quát
Định 4. Cho c
1
,c
2
, ..., c
k
các hằng số thực, với c
k
 0.
Giả sử PTĐT: r
k
-c
1
r
k-1
-c
2
r
k-2
-...-c
k
= 0
t nghiệm phân biệt r
1
,r
2
, ..., r
t
vibitương ng
m
1
,…,m
t
(với m
1
+…+m
t
= k).
Khi đó, dãy {a
n
} nghiệm của CTĐQ TTTN hệ số hằng
a
n
=c
1
a
n-1
+c
2
a
n-2
+...+ c
k
a
n-k
,
khi chỉ khi
a
n
= (
,
+
,
n + … +
,

𝑛

) 𝑟
+
(
,
+
,
n + … +
,

𝑛

) 𝑟
+ ...
(
t,0
+
,
n + … +
,

𝑛

) 𝑟
với n=0,1,2,… và
i,j
các hằng số 1 i t
0 j m
i
-1 dựa vào các điều kiện đầu
k
i
inin
aca
1
0
1
k
i
ik
i
k
rcr

t
i
n
i
m
j
j
jin
rna
i
1
1
0
,
142
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 5
Giải công thức đệ qui:
c
n
= 4c
n-1
+ 3c
n-2
+ 18c
n-3
, n 3,
c
0
= 1; c
1
= 2; c
2
= 13.
Giải: Phương trình đặc trưng
r
3
+ 4r
2
–3r 18 = (r 2)(r + 3)
2
= 0
Vậy nghiệm tổng quát của công thức:
143
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy: Các phương pháp khác
Trên thực tế, khi phân tích độ phức tạp của một thuật toán nào đó nhờ
sử dụng công thức đệ quy tuyến tính, thì công thức đệ quy ít khi
bậc lớn hơn 2.
Do đó, ta cũng thể sử dụng hai phương pháp sau đây để giải công
thức đệ quy
Thay thế quay lui: xuất phát từ công thức đã cho, ta thế lần lượt lùi về các số
hạng phía trước của công thức đệ quy
Cây đệ quy: biểu diễn công thức đệ quy bởi một cây đệ quy. Xuất phát từ công
thức đệ quy đã cho, ta biểu diễn các số hạng đệ quy kích thước dữ liệu đầu
vào lớn ở mức A nào đó trên cây bởi các dữ liệu đầu vào nhỏ hơn ở mức A+1
của vây, và tính các số hạng không đệ quy. Cuối cùng, tính tổng tất cả các số
hạng không đệ quy ở tất cả các mức của cây.
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
dụ 1: Giải công thức đệ quy
T(n)= T(n-1) + 2n
với T(1) = 5
Giải:
Ta tiến hành thay thế lần lượt các số hạng của công thức đệ quy bằng cách lùi
lại các số hạng phía trước:
T(n) = T(n-1) + 2n
= T((n-1) -1) + 2(n-1) + 2n
= T(n-2) + 2 (n-1) + 2n
= T((n-2)-1) + 2(n-2) + 2(n-1) + 2n
= T(n-3) +2(n-2) + 2(n-1) + 2n
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
Tiếp tục thay thế lùi ta được
T(n) = T(n-3) + 2(n-2) + 2(n-1) + 2n
= T(n-4) + 2(n-3) + 2(n-2) + 2(n-1) + 2n
…………
= T(n-i) +
2󰇛𝑛 𝑗󰇜


giá tr hàm tibước thay thế th i
Giải công thức tổng
2󰇛𝑛 𝑗󰇜


ta được
T(n) = T(n-i) + 2n(i-1) – 2(i-1)(i-1+1)/2 + 2n
= T(n-i) + 2n(i-1) – i
2
+ i + 2n (1)
Giờ ta muốn loại bỏ số hạng T(n-i). Để làm được điều này, tại bước lặp thay thế thứ bao
nhiêu ta thu được điều kiện đầu T(1)?
Nhận thấy thu được T(1) khi n - i =1, tức i = n -1
Thay thế vào biểu thức (1) ta
T(n) = T(1) + 2n(n-1-1) (n-1)
2
+ (n-1) + 2n
= 5 + 2n(n-2) – (n
2
-2n+1) + (n-1) + 2n = n
2
+ n + 3
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
dụ 2: Giải công thức đệ quy
T(n)= T(n/2) + c
với T(1) = 2, và c hằng số
T(n) =
T(n/2) + c thay thế T(n/2)
= T(n/4) + c + c thay thế T(n/4)
= T(n/8) + c + c + c
= T(n/2
3
) + 3c
= …
= T(n/2
k
) + kc
T(n) = T(n/2
logn
) + clogn
“chn k = logn”
= T(n/n) + clogn
= T(1) + clogn = 2 +clogn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 3
Hàm tính giai thừa
Xét thuật toán đệ quy tính n!
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bao nhiêu lần hàm Factorial được gọi khi chúng ta thực hiện lệnh Factorial(n); ?
Khi n = 1, hàm Factorial được gọi 1 lần T(1) = 1
Khi n > 1:
Gọi hàm Factorial 1 lần,
Cộng với số lần gọi trong lệnh đệ quy Factorial(n − 1) T(n-1)
Do đó ta có công thức đệ quy:
T(1) = 1
T(n) = 1 + T(n − 1), n >1
Factorial(n);
Tìm công thức dạng hiện tính T(n) với
mọi giá trị của n
T(n)=1+T(n‐1)
dụ 3
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
T(n) = T(n − 1) + 1, n >1
= [T(n-2) +1] + 1 [có 2 số “1”]
=[[T(n-3)+1]+1]+1 [có 3 số “1”]
=….
= T(n –(n-1)) + (n-1) [có n-1 số 1”]
= T(1) + (n-1)
= 1 + (n-1)
= n
Factorial(n);
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
bao nhiêu phép nhân M(n) được thực thi khi thực hiện hàm Factorial?
Khi n = 1 không phép nhân nào được thực hiện M(1) = 0
Khi n > 1:
Ta thực hiện 1 lần phép nhân.
Cộng với số lần thực hiện phép nhân trong lệnh gọi đệ quy Factorial(n − 1) M(n-1)
Do đó ta có công thức đệ quy:
M(0) = 0; M(1) = 0
M(n) = 1 + M(n − 1), n >1
dụ 4
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
5. (Bμito¸nth¸pHμ néi). T ch¬i th¸p Hμ néi ®ưîc trình bμynhư sau: 3
cäca,b,c.Trªncäcacãmétchånggåmnc¸Üưêng kÝnh gi¶m dÇn dưíi lªn
trªn. CÇn ph¶i chuyÓn chång ®Üa cäc a sang cäc c tu©n thñ qui t¾c:
1. Milnch chuyn1đĩa
2. Chỉđưcxếp đĩacóđường kính nh hơnlêntrênđĩacóđường kính lnhơn.
Trong qu¸ trình chuyÓn ®ưîc phÐp dïng cäc b lμm cäc trung gian.
Bμito¸Ætralμ: Tìm công thức đệ qui cho h
n
là lÇn di chuyÓn ®Üa Ýt nhÊt cÇn thùc
hiÖn ®Ó hoànthành nhiÖm ®Æt ra trong trß ch¬i th¸p Hμ néi.
Cọc a Cọc c Cọc b
152
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Tower of Hanoi: n=5
Cọc a Cọc c Cọc b
153
1. Milnch chuyn1đĩa
2. Chỉđưcxếp đĩacóđường kính nh hơn lên trên đĩacóđường kính lnhơn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Bài toán: chuyển n đĩa từ cọc a sang cọc c sử dụng cọc b làm trung gian
Cần tìm h
n
là sè lÇn di chuyÓn ®Üa Ýt nhÊt cÇn thùc hiÖn
Cọc a Cọc c Cọc b
(1) ChuyÓn n-1 ®Üa cäc a ®Õn cäc b dông cäc c lμm trung gian.
(2) ChuyÓn 1 ®Üa (®Üa víi ®ưêng kÝnh lín nhÊt) cäc a ®Õn cäc c.
(3) ChuyÓn n-1 ®Üa cäc b ®Õn cäc c (sö dông cäc a lμm trung gian).
Bài toán kích thước n-1 Số lần di chuyển = h
n-1
Bài toán kích thước n-1 Số lần di chuyển = h
n-1
Số lần di chuyển = 1
h
n
=2h
n-1
+1,n 2.
ViÖc di chuyÓn ®Üa gåm 3 bưíc:
154
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
Tower of Hanoi: n=5
Cọc a Cọc c Cọc b
(1) ChuyÓn n-1 ®Üa cäc a ®Õn cäc b dông cäc c lμm trung gian.
(2) ChuyÓn 1 ®Üa (®Üa víi ®ưêng kÝnh lín nhÊt) cäc a ®Õn cäc c.
(3) ChuyÓn n-1 ®Üa cäc b ®Õn cäc c (sö dông cäc a lμm trung gian).
Bài toán kích thước n-1 Số lần di chuyển = h
n-1
Bài toán kích thước n-1 Số lần di chuyển = h
n-1
Số lần di chuyển = 1
155
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
Ta thể tìm được công thức trực tiếp cho h
n
bằng phương pháp thế
quay lui:
h
n
= 2 h
n−1
+ 1
= 2 (2 h
n−2
+ 1) + 1 = 2
2
h
n−2
+ 2 + 1
= 2
2
(2 h
n−3
+ 1) + 2 + 1 = 2
3
h
n−3
+ 2
2
+ 2 + 1
= 2
n−1
h
1
+ 2
n−2
+ … + 2 + 1
= 2
n−1
+ 2
n−2
+ … + 2 + 1
(do h
1
= 1)
= 2
n
− 1
156
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 3: Cây đệ quy
Để giải công thức đệ quy bằng phương pháp này: ta sẽ vẽ cây đệ quy tả công thức đã
cho
Mỗi nút của cây tương ứng với 1 hàm dữ liệu đầu vào. Càng đi xuống phía dưới y,
kích thước dữ liệu đầu vào càng giảm.
Mức cuối cùng của cây tương ứng với kích thước dữ liệu đầu vào nhỏ nhất
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 1: Thuật toán đệ quy giải bài toán dãy con lớn nhất
158
O(n)
O(n)
T(n/2)
T(n/2)
T(n) = 2T(n/2)+O(n)
Giải bằng phương pháp cây đệ
quy, ta sẽ thu được:
T(n) = O(nlogn)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 1: Giải công thức đệ quy:
T(n) = 2T(n/2) + n, T(1) = 4
Giá trị hàm T(n) bằng tổng các giá trị tại tất cả các mức:
mức cuối (sâu nhất) log
2
n có giá trị = 4n, ta có
n*4
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 3: Cây đệ quy
dụ 2: Giải công thức đệ quy
T(n) = T(n/) + f(n), T() = c
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
dụ 2: Giải công thức đệ quy
T(n) = T(n/) + f(n), T() = c
Iteration
0
1
2
.
.
i
.
log
n
TT(n)
T(n/) T(n/) T(n/) 
T(n/
2
) T(n/
2
)  T(n/
2
) T(n/
2
) 
Cost
f(n)
f(n/)
2
f(n/
2
)
.
.
i
f(n/
i
)
.
Giá trị của hàm bằng tổng các giá trị trên tất cả các mức của cây:
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
162
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT ĐHBK HN
Đầu vào: Mảng S gồm n phần tử: S[0],…,S[n-1] đã sắp xếp theo thứ tự
tăng dần; Giá trị
key.
Đầu ra: chỉ số của phần tử giá trị
key nếu có; -1 nếu key không xuất
hiện trong mảng S
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
163
82134657 109111214130
641413 25 33 5143 53 8472 93 95 97966
lo
hi
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
164
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo
hi
mid
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
165
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo
hi
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
166
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo
mid hi
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
167
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo hi
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
168
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo himid
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
169
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo
hi
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
170
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo
hi
mid
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
171
821 3 4 65 7 109 11 12 14130
641413 25 33 5143 53 8472 93 95 97966
lo
hi
mid
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
key=33
key=31??
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
172
Đầu vào: Mảng S gồm n phần tử: S[0],…,S[n-1] đã sắp xếp theo thứ tự
tăng dần; Giá trị
key.
Đầu ra: chỉ số của phần tử giá trị
key nếu có; -1 nếu key không xuất
hiện trong mảng S
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
binsearch(0, n-1, S, key);
bao nhiêu lần hàm binsearch được gọi trong trường hợp tồi nhất ?
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
173
int binsearch(int low, int high, int S[], int key)
{
if (low <= high)
{
mid = (low + high) / 2;
if (S[mid]==key) return mid;
else if (key < S[mid])
return binsearch(low, mid-1, S, key);
else
return binsearch(mid+1, high, S, key);
}
else return -1;
}
T(0) = 1
T(1) = 2
T(2) = T(1) + 1 = 3
T(4) = T(2) + 1 = 4
T(8) = T(4) + 1 = 4 + 1 = 5
T(n) = T(n/2) + 1
Công thc đệ quy:
T(n)=T(n/2) + 1
T(0) = 1
T(1) = 2
Gọi T(n): số lần hàm binsearch được gọi trong trường hợp tồi nhất khi mảng S n phần tử
binsearch(0, n-1, S, key);
binsearch(0, -1, S, key);
T(0) = ?
T(1) = ?
binsearch(0, 0, S, key);
binsearch(0, -1, S, key);
binsearch(1, 0, S, key);
dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Bài tập:Hãy giải công thức đệ quy y
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)
lOMoARcPSD|36442750
| 1/173

Preview text:

lOMoARcPSD|36442750
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
Cấu trúc dữ liệu và giải thuật
Nguyễn Khánh Phương
Computer Science department
School of Information and Communication technology
E-mail: phuongnk@soict.hust.edu.vn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung khóa học
Chương 1. Các khái niệm cơ bản
Chương 2. Các cấu trúc dữ liệu cơ bản Chương 3. Cây Chương 4. Sắp xếp Chương 5. Tìm kiếm 2
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
Chương 1. Các khái niệm cơ bản
Nguyễn Khánh Phương
Computer Science department
School of Information and Communication technology
E-mail: phuongnk@soict.hust.edu.vn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung 1.1. Ví dụ mở đầu
1.2. Thuật toán và độ phức tạp 1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số kĩ thuật phân tích thuật toán
1.6. Giải công thức đệ quy 4
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung 1.1. Ví dụ mở đầu
1.2. Thuật toán và độ phức tạp 1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số kĩ thuật phân tích thuật toán
1.6. Giải công thức đệ quy 5
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Tìm dãy con lớn nhất (The maximum subarray problem)
• Cho dãy số gồm n số:
a1, a2, … , an
Dãy gồm liên tiếp các số a , a
với 1 ≤ i j n được gọi là dãy i i+1 , …, aj
con của dãy đã cho và ∑
𝑎 được gọi là trọng lượng của dãy con này
Bài toán đặt ra là: Hãy tìm trọng lượng lớn nhất của các dãy con, tức là
tìm cực đại giá trị
𝑎 . Ta gọi dãy con có trọng lượng lớn nhất là dãy con lớn nhất.
Ví dụ: Cho dãy số -2, 11, -4, 13, -5, 2 thì cần đưa ra câu trả lời là 20 (dãy con
lớn nhất là 11, -4, 13 với giá trị = 11+ (-4)+13 =20 )
 Để giải bài toán này, ta có thể dùng nhiều cách khác nhau, ví du duyệt toán
bộ (brute force), chia để chị (divide and conquer), quy hoạch động (dynamic programming), ... 6
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Tìm dãy con lớn nhất (The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ có cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming)
NGUYỄN KHÁNH PHƯƠNG 7
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Tìm dãy con lớn nhất (The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ có cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming) 8
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.1. Thuật toán duyệt toàn bộ giải bài toán dãy con lớn nhất
• Thuật toán đơn giản đầu tiên có thể nghĩ để giải bài toán đặt
ra là: Duyệt tất cả các dãy con có thể : a , a
với 1 ≤ i j n, i i+1 , …, aj
và tính tổng của mỗi dãy con để tìm ra trọng lượng lớn nhất.
• Trước hết nhận thấy rằng, tổng số các dãy con có thể của dãy đã cho là:
C(n, 1) + C(n, 2) = n2/2 + n/2 9
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ ứng dụng
• Giả sử ta biết giá của cổ phiếu của công ty A từ ngày i đến ngày j như sau: Ngày 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Giá 100 112 109 85 105 102 86 63 81 101 94 106 101 79 93 89 95
• Ta cần mua một số cổ phiếu, duy nhất 1 lần, rồi bán ra tại một ngày nào đó sau đấy.
• Làm thế nào để tối đa hóa lợi nhuận ?
– Chiến lược: mua vào lúc giá thấp, bán ra lúc giá cao [buy low, sell high] không phải lúc nào cũng cho lợi nhuận cao nhất
Ví dụ: Cho giá cổ phiếu như ở đồ thị. Ta thu được lợi nhuận cao nhất là 3$ nếu mua vào ở thứ 2 với giá
7$, và bán ra ở ngày thứ 3 với giá 10$. Giá 7$ mua vào ở ngày 2 không phải là giá thấp nhất, và giá 10$
bán ra ở ngày 3 cũng không phải là giá cao nhất
– Lời giải: Ta dễ dàng tìm được bằng cách duyệt hết tất cả các khả năng:
• Có bao nhiêu cặp ngày mua/bán có thể có trong khoảng thời gian n ngày?
• Tính lợi nhuận thu được cho mỗi cặp ngày, để tìm cặp ngày có lợi nhuận cao nhất
– Liệu ta có thể làm tốt hơn hay không? 10
• Câu trả lời: Có, bằng cách quy về bài toán dãy con lớn nhất
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Quy về bài toán dãy con lớn nhất Ngày 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Giá 100 112 109 85 105 102 86 63 81 101 94 106 101 79 93 89 95
• Tìm dãy các ngày liên tiếp sao cho:
– Tổng lượng giá thay đổi ở ngày cuối so với ngày đầu là lớn nhất
• Nhìn vào giá của từng ngày
– Lượng giá thay thay đổi vào ngày i: giá cổ phiếu ngày i trừ đi giá cổ phiếu ngày i-1
– Ta có mảng giá thay đổi như sau: Ngày 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Giá 100 112 109 85 105 102 86 63 81 101 94 106 101 79 93 89 95 Thay 12 ‐3 ‐24 20 ‐3 ‐16 ‐23 18 20 ‐7 12 ‐5 ‐22 14 ‐4 6 đổi
– Tìm dãy con liên tiếp có tổng lớn nhất
Dãy con lớn nhất
e.g.: 12,-3,-24,20,-3,-16,-23,18,20,-7,12,-5,-22,14,-4,6
Dãy con lớn nhất: 18+20+(-7)+12 = 43
 Mua sau ngày thứ 7, bán ra sau ngày thứ 11: mua với giá = 63, bán ra với lúc = 106  Lợi nhuận =106-63=43 11
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con Chỉ số i 0 1 2 3 4 5 a[i] ‐2 11 ‐4 13 ‐5 2
i = 0: (-2), (-2, 11), (-2,11, -4), (-2,11,-4,13), (-2,11,-
4,13,-5), (-2,11,-4,13,-5,2)
i = 1: (11), (11, -4), (11, -4, 13), (11, -4, 13, -5), (11, -4, 13, -5, 2)
i = 2: (-4), (-4, 13), (-4, 13, -5), (-4,13,-5,2)
i = 3: (13), (13,-5), (13, -5,2) i = 4: (-5), (-5, 2) int maxSum = 0; i = 5: (2) for (int i=0; i for (int j=i; j
Với mỗi chỉ số i : duyệt tất cả các dãy con bắt đầu từ phần tử int sum = 0;
a[i] có 1 phần tử, có 2 phần tử, … :
for (int k=i; k<=j; k++)
i = 0: tất cả các dãy con bắt đầu từ a[0] có 1 phần tử, 2 phần tử, … 6 phần tử sum += a[k];
i = 1: tất cả các dãy con bắt đầu từ a[1] có 1 phần tử, 2 phần if (sum > maxSum) tử, … 5 phần tử • … maxSum = sum;
i = 5: tất cả các dãy con bắt đầu từ a[5] có 1 phần tử } 12 }
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
Phân tích thuật toán: Ta sẽ tính số lượng phép cộng mà thuật toán phải thực hiện, tức là đếm xem dòng lệnh sum += a[k]
phải thực hiện bao nhiều lần. Số lượng phép cộng là: n 1  n 1  n 1  n 1
 (n i)(n i 1)
( j i 1) (1 2. .(ni))  
i0 ji i0 i0 2 1 n 1 n n  2
 1 n(n 1)(2n 1) n(n 1)
 k(k 1)       2 k k         k 1  2 k 1 k 1  2 6 2 3 2 n n n int maxSum = 0;    6 2 3 for (int i=0; i for (int j=i; j int sum = 0;
for (int k=i; k<=j; k++) sum += a[k]; if (sum > maxSum) maxSum = sum; } 13 }
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Tìm dãy con lớn nhất (The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ có cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming) 14
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.2. Duyệt toàn bộ có cải tiến
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con Chỉ số i 0 1 2 3 4 5 a[i] ‐2 11 ‐4 13 ‐5 2
i = 0: (-2), (-2, 11), (-2,11, -4), (-2,11,-4,13), (-2,11,-4,13,-5), (-2,11,- 4,13,-5,2)
i = 1: (11), (11, -4), (11, -4, 13), (11, -4, 13, -5), (11, -4, 13, -5, 2)
i = 2: (-4), (-4, 13), (-4, 13, -5), (-4,13,-5,2)
i = 3: (13), (13,-5), (13, -5,2) i = 4: (-5), (-5, 2) i = 5: (2) int maxSum = 0; int maxSum = a[0]; for (int i=0; i for (int i=0; i for (int j=i; j int sum = 0; int sum = 0; for (int j=i; j
for (int k=i; k<=j; k++) sum += a[j]; sum += a[k]; if (sum > maxSum) if (sum > maxSum) maxSum = sum; maxSum = sum; } } } 1515 }
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.2. Duyệt toàn bộ có cải tiến
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
Cài đặt cải tiến:
Nhận thấy, ta có thể tính tổng các phần tử từ vị trí i đến j từ tổng của các phần
tử từ i đến j-1 chỉ bằng 1 phép cộng: j j 1 
 [ak] [a j] [ak] k i k i
Tổng các phần tử từ i đến j
Tổng các phần tử từ i đến j-1 int maxSum = 0; int maxSum = a[0]; for (int i=0; i for (int i=0; i for (int j=i; j int sum = 0; int sum = 0; for (int j=i; j
for (int k=i; k<=j; k++) sum += a[j]; sum += a[k]; if (sum > maxSum) if (sum > maxSum) maxSum = sum; maxSum = sum; } } } } 16
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.2. Duyệt toàn bộ có cải tiến
Thuật toán duyệt toàn bộ: duyệt tất cả các dãy con
Phân tích thuật toán. Ta lại tính số lần thực hiện phép cộng: Sum += a[j] Và thu được kết quả: n 1  2
(  )  ( 1)...1 n n n i n n   i0 2 2
• Để ý rằng số này là đúng bằng số lượng dãy con. Dường như thuật toán thu được là
rất tốt, vì ta phải xét mỗi dãy con đúng 1 lần. int maxSum = a[0]; for (int i=0; i int sum = 0; for (int j=i; j sum += a[j]; if (sum > maxSum) maxSum = sum; } 17 }
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Tìm dãy con lớn nhất (The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ có cải tiến
1.1.3 Thuật toán đệ quy (Recursive algorithm)
1.1.4. Thuật toán quy hoạch động (Dynamic programming) 18
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
• Ta còn có thể xây dựng thuật toán tốt hơn nữa bằng kỹ thuật chia để trị
(divide-and-conquer). Kỹ thuật này bao gồm các bước sau:
– Chia bài toán cần giải ra thành các bài toán con cùng dạng
– Giải mỗi bài toán con một cách đệ qui
Trường hợp cơ sở: khi bài toán con có kích thước đủ nhỏ, ta giải
nó bằng phương pháp duyệt toàn bộ.
– Tổ hợp lời giải của các bài toán con để thu được lời giải của bài toán xuất phát.
• Để giải bài toán dãy con lớn nhất:
– Sử dụng phần tử chính giữa để chia đôi dãy đã cho thành hai dãy con (gọi tắt là
dãy nửa trái và dãy nửa phải) với độ dài giảm đi một nửa low mid high mid +1
Nửa trái A[low..mid]
Nửa phải A[mid+1..high] 19
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
• Để tổ hợp lời giải, nhận thấy rằng dãy con lớn nhất A[i..j] của dãy A[low..high] chỉ có thể xảy ra một
trong 3 trường hợp (với mid = (low+high)/2):
– Dãy con lớn nhất nằm ở dãy nửa bên trái A[low..mid] (low i j mid)
– Dãy con lớn nhất nằm ở dãy nửa bên phải A[mid+1..high] (mid < i j high)
– Giao điểm giữa mid (low i mid < j high) {dãy con lớn nhất bắt đầu ở nửa trái và kết thúc ở nửa phải}
• Do đó, nếu kí hiệu trọng lượng của dãy con lớn nhất ở nửa trái là wL, ở nửa phải làwR, và giao điểm giữa
là wM, thì trọng lượng lớn nhất cần tìm là max(wL, wR, wM) 20
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
• Việc tìm trọng lượng của dãy con lớn nhất ở nửa trái (wL) và nửa phải (wR) có thể thực hiện một cách đệ quy:
– Trường hợp cơ sở (base case): dãy nửa trái / phải chỉ gồm duy nhất 1 phần tử
• Để tìm trọng lượng wM của dãy con lớn nhất bắt đầu từ nửa trái và kết thúc ở nửa phải, ta thực hiện như sau:
– Ở dãy nửa trái: tìm trọng lượng wML của dãy con lớn nhất kết thúc ở điểm chia mid
– Ở dãy nửa phải: tính trọng lượng wMR của dãy con lớn nhất bắt đầu ở vị trí mid+1 – Khi đó wM = wML + wMR. 21
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: tính trọng lượng wM của dãy con lớn nhất bắt đầu ở dãy nửa trái và kết thúc ở dãy nửa phải mid =5 Ở dãy nửa trái: 1 2 3 4 5 6 7 8 9 10 A 13 ‐3 ‐25 20 ‐3 ‐16 ‐23 18 20 ‐7 S[5 .. 5] = -3 S[4 .. 5] = 17  (max_left = 4) S[3 .. 5] = -8 S[2 .. 5] = -11 S[1 .. 5] = 2 mid =5 Ở dãy nửa phải: 1 2 3 4 5 6 7 8 9 10 A 13 ‐3 ‐25 20 ‐3 ‐16 ‐23 18 20 ‐7 S[6 .. 6] = -16 S[6 .. 7] = -39 S[6 .. 8] = -21 S[6 .. 9] = (max_right = 9)  -1 S[6..10] = -8
 Dãy con lớn nhất giao điểm chia mid S[4..9] = 17+ (-1) = 16 22
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Tính trọng lượng wM của dãy con lớn nhất bắt đầu ở dãy nửa trái và kết thúc ở dãy nửa phải
– Ở dãy nửa trái: tìm trọng lượng wML của dãy con lớn nhất kết thúc ở điểm chia mid
– Ở dãy nửa phải: tính trọng lượng wMR của dãy con lớn nhất bắt đầu ở vị trí mid+1 • Khi đó wM = wML + wMR.
wM = MaxLeft(a,low,mid) + MaxRight(a,mid,high); 23
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
Phân tích thuật toán: Ta cần tính xem lệnh gọi MaxSub(a,1,n) để thực hiện thuật toán đòi hỏi bao nhiêu phép cộng?
• Thủ tục MaxLeft và MaxRight yêu cầu
n/2 + n/2 = n phép cộng
• Vì vậy, nếu gọi T(n) là số phép cộng mà lệnh maxSub(a, 1, n) cần thực hiện, ta có công thức đệ quy sau: 0 n  1 
T (n)   (n) (n)  2 (n T T n T )  n n   1  2 2 2
Giải công thức đệ quy này, ta có T(n) = n log n 24
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.3. Thuật toán đệ quy giải bài toán dãy con lớn nhất
Ví dụ: để tìm dãy con lớn nhất cho mảng a gồm 10 phần tử cho ở bảng dưới đây 1 2 3 4 5 6 7 8 9 10 13 ‐3 ‐25 20 ‐3 ‐16 ‐23 18 20 ‐7
Ta sẽ phải gọi lệnh: MaxSub(a, 1, 10) 25
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Bài toán dãy con lớn nhất: so sánh thời gian tính của các thuật toán
Số lương phép cộng mà mỗi thuật toán cần thực hiện là: 1.1.1. Duyệt toàn bộ
1.1.2. Duyệt toàn bộ có cải tiến
1.1.3 Thuật toán đệ quy: n log n
 Cùng một bài toán, ta đã đề xuất 3 thuật toán đòi hỏi số lượng phép toán khác nhau,
và vì thế sẽ đòi hỏi thời gian tính khác nhau.
Bảng dưới đây cho thấy thời gian tính của 3 thuật toán trên, với giả thiết: máy tính có
thể thực hiện108 phép cộng trong một giây Độ phức tạp n=10 Thời gian n=100 Thời gian n=104 Thời gian n=106 Thời gian n3 103 10-5 giây 106 10-2 giây 1012 2.7 hours 1018 115 ngày n2 100 10-6giây 10000 10-4 giây 108 1 giây 1012 2.7 giờ n log n 33.2 3.3*10-8giây 664 6.6*10-6 giây 1.33*105 10‐3 giây 1.99*107 2*10‐1 sec en 2.2*104 1*10-4 giây 2.69*1043 >1026 thế kỉ 8.81*104342 >104327 thế kỉ
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Bài toán dãy con lớn nhất: so sánh thời gian tính của các thuật toán Độ phức tạp n=10 Thời gian n=100 Thời gian n=104 Thời gian n=106 Thời gian n3 103 10-5 giây 106 10-2 giây 1012 2.7 hours 1018 115 ngày n2 100 10-6giây 10000 10-4 giây 108 1 giây 1012 2.7 giờ n log n 33.2 3.3*10-8giây 664 6.6*10-6 giây 1.33*105 10‐3 giây 1.99*107 2*10‐1 sec en 2.2*104 1*10-4 giây 2.69*1043 >1026 thế kỉ 8.81*104342 >104327 thế kỉ
• Với n nhỏ thời gian tính là không đáng kể.
• Vấn đề trở nên nghiêm trọng hơn khi n > 106. Lúc đó chỉ có thuật
toán thứ ba (thời gian nlogn) là có thể áp dụng được trong thời gian thực.
• Còn có thể làm tốt hơn nữa không?
– Yes! Có thể đề xuất thuật toán chỉ đòi hỏi n phép cộng! 27
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Tìm dãy con lớn nhất (The maximum subarray problem)
1.1.1. Duyệt toàn bộ (Brute force)
1.1.2. Duyệt toàn bộ có cải tiến
1.1.3. Thuật toán đệ quy (Recursive algorithm) n log n
1.1.4. Thuật toán Quy hoạch động (Dynamic programming) n 28
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất
Thuật toán quy hoạch động được chia làm 3 giai đoạn:
1. Phân rã (Divide): chia bài toàn cần giải thành những bài toán con
(Bài toán con (Subproblem): là bài toán có cùng dạng với bài toán đã
cho, nhưng kích thước nhỏ hơn)
2. Ghi nhận lời giải: lưu trữ lời giải của các bài toán con vào 1 bảng
3. Tổng hợp lời giải: Lần lượt từ lời giải của các bài toán con kích
thước nhỏ hơn tìm cách xây dựng lời giải của bài toán kích thước lớn
hơn, cho đến khi thu được lời giải của bài toán xuất phát (là bài toán
con có kích thước lớn nhất). 29
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất
Thuật toán quy hoạch động được chia làm 3 giai đoạn: 1. Phân rã: •
Gọi s là trọng lượng của dãy con lớn nhất của dãy a
, i = 1, 2, ..., n. i 1, a2, ..., ai
Rõ ràng, s là giá trị cần tìm (lời giải của bài toán). n 3. Tổng hợp lời giải: • s1 = a1 •
Giả sử i > 1 và ta đã biết giá trị s với k = 1, 2, ..., i-1. Ta cần tính giá trị s là trọng lượng của dãy con lớn nhất k i của dãy:
a1, a2, ..., a . i-1, ai
Nhận thấy rằng: dãy con lớn nhất của dãy a1, a2, . ., a
có thể hoặc bao gồm phần tử a hoặc không bao gồm i-1, ai i
phần tử a  do đó, dãy con lớn nhất của dãy a
chỉ có thể là một trọng 2 dãy sau: i
1, a2, ..., ai-1, ai
– Dãy con lớn nhất của dãy a1, a2, ..., ai-1
– Dãy con lớn nhất của dãy a1, a2, ..., a , và dãy con này kết thúc tại phần tử a . i i  Do đó, ta có s = max {s
}, i = 2, …, n. i i-1, ei
với e là trọng lượng của dãy con lớn nhất a
và dãy con này kết thúc tại a . i 1, a2, ..., ai i
Để tính e , ta xây dựng công thức đệ quy: ie1 = a1;
e = max {a , e
}, i = 2, ..., n. i i i-1 + ai 30
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất
Thuật toán quy hoạch động được chia làm 3 giai đoạn: 1. Phân rã: •
Gọi s là trọng lượng của dãy con lớn nhất của dãy a
, i = 1, 2, ..., n. i 1, a2, ..., ai
Rõ ràng, s là giá trị cần tìm (lời giải của bài toán). n 3. Tổng hợp lời giải: • s1 = a1 •
Giả sử i > 1 và ta đã biết giá trị s với k = 1, 2, ..., i-1. Ta cần tính giá trị s là trọng lượng của dãy con lớn nhất k i của dãy:
a1, a2, ..., a . i-1, ai
Nhận thấy rằng: dãy con lớn nhất của dãy a1, a2, . ., a
có thể hoặc bao gồm phần tử a hoặc không bao gồm i-1, ai i
phần tử a  do đó, dãy con lớn nhất của dãy a
chỉ có thể là một trọng 2 dãy sau: i
1, a2, ..., ai-1, ai
– Dãy con lớn nhất của dãy a1, a2, ..., ai-1
– Dãy con lớn nhất của dãy a1, a2, ..., a , và dãy con này kết thúc tại phần tử a . i i  Do đó, ta có s = max {s
}, i = 2, …, n. i i-1, ei
với e là trọng lượng của dãy con lớn nhất a
và dãy con này kết thúc tại a . i 1, a2, ..., ai i
Để tính e , ta xây dựng công thức đệ quy: ie1 = a1;
e = max {a , e
}, i = 2, ..., n. i i i-1 + ai 31
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.1.4. Thuật toán quy hoạch động giải bài toán dãy con lớn nhất MaxSub(a) { smax = a[1];
// smax : trọng lượng của dãy con lớn nhất ei = a[1];
// ei: trọng lượng của dãy con lớn nhất kết thúc tại phần tử a[i] imax = 1;
// imax : chỉ số của phần tử cuối cùng thuộc dãy con lớn nhất for i = 2 to n { u = ei + a[i]; v = a[i]; if (u > v) ei = u else ei = v; if (ei > smax) { smax := ei; imax := i; } } }
Phân tích thuật toán:
Số phép cộng phải thực hiện trong thuật toán
= Số lần thực hiện câu lệnh u = ei + a[i] = n 32
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
So sánh 4 thuật toán
• Bảng sau cho thấy ước tính thời gian tính của 4 thuật toán đề xuất ở trên
(với giả thiết máy tính có thể thực hiện 108 phép cộng trong 1 giây) Thuật toán Độ phức tạp n=104 Thời gian n=106 Thời gian Duyệt toàn bộ n3 1012 2.7 giờ 1018 115 ngày Duyệt toàn bộ có n2 108 1 giây 1012 2.7 giờ cải tiến Đệ quy n log n 1.33*105 10‐3 giây 1.99*107 2*10‐1 giây (Recursive) Quy hoạch động n 104 10‐4 giây 106 2*10‐2 giây (Dynamic programming)
• Ví dụ này cho ta thấy việc phát triển được thuật toán hiệu quả có thể
giảm bớt được chi phí thời gian một cách đáng kể như thế nào. 33
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung 1.1. Ví dụ mở đầu
1.2. Thuật toán và độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số kĩ thuật phân tích thuật toán
1.6. Giải công thức đệ quy 34
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Thuật toán (Algorithm)
• Thuật ngữ algorithm xuất phát từ tên của nhà toán học người Ba Tư: Abu Ja’far
Mohammed ibn-i Musa al Khowarizmi.
• Trong ngành khoa học máy tính, thuật ngữ “thuật toán” được dùng để chỉ một
phương pháp bao gồm một chuỗi các câu lệnh mà máy tính có thể sử dụng để giải quyết một bài toán.
Định nghĩa. Ta hiểu thuật toán giải bài toán đặt ra là một thủ tục xác định bao gồm
một dãy hữu hạn các bước cần thực hiện để thu được đầu ra (output) cho một đầu
vào cho trước (input) của bài toán. Input Algorithm Output
• Ví dụ: Bài toán tìm số nguyên lớn nhất trong một dãy các số nguyên dương cho trước
• Đầu vào (Input) : dãy gồm n số nguyên dương a1, a2, …, an
• Đầu ra (Output): số có giá trị lớn nhất của dãy đã cho
• Ví dụ: Input 12 8 13 9 11  Output: 12 35
• Yêu cầu: thiết kế thuật toán giải bài toán trên
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Tìm số lớn nhất trong dãy số gồm 5 số nguyên sau: 36
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Các bước trong thuật toán FindLargest
Đặt Largest = phần tử đầu tiên của dãy
Nếu phần tử thứ hai lớn hơn Largest: đặt Largest = phần tử thứ hai của dãy
Nếu phần tử thứ ba lớn hơn Largest: đặt Largest = phần tử thứ ba của dãy
Nếu phần tử thứ tư lớn hơn Largest: đặt Largest = phần tử thứ tư của dãy
Nếu phần tử thứ năm lớn hơn Largest: đặt Largest = phần tử thứ năm của dãy
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
FindLargest chỉnh sửa cho hợp lý Đặt Largest = 0
Nếu số hiện tại lớn hơn Largest, đặt Largest = số hiện tại
Nếu số hiện tại lớn hơn Largest, đặt Largest = số hiện tại
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Tổng quát hàm FindLargest Đặt Largest = 0
Nếu số hiện tại lớn hơn Largest, đặt Largest = số hiện tại
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Thuật toán
• Thuật toán có các đặc trưng sau đây:
Đầu vào (Input): Thuật toán nhận dữ liệu vào từ một tập nào đó.
Đầu ra (Output): Với mỗi tập các dữ liệu đầu vào, thuật toán đưa ra các dữ liệu
tương ứng với lời giải của bài toán.
Chính xác (Precision): Các bước của thuật toán được mô tả chính xác.
Hữu hạn (Finiteness): Thuật toán cần phải đưa được đầu ra sau một số hữu hạn
(có thể rất lớn) bước với mọi đầu vào.
Đơn trị (Uniqueness): Các kết quả trung gian của từng bước thực hiện thuật
toán được xác định một cách đơn trị và chỉ phụ thuộc vào đầu vào và các kết quả của các bước trước.
Tổng quát (Generality): Thuật toán có thể áp dụng để giải mọi bài toán có dạng đã cho. 40
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ: Xây dựng thuật toán giải bài toán
• Bài toán: Thiết kế chương trình sắp xếp n >= 1 số nguyên theo thứ tự không giảm
– Input: Tập n số nguyên: a[1], a[2],…, a[n]
– Output: Tập n số nguyên đã được sắp xếp: a[1] ≤ a[2] ≤... ≤ a[n] • Bước I – Phân tích
– Từ dãy số chưa được sắp xếp, ta tìm số nhỏ nhất và đặt số này vào vị trí tiếp theo trong dãy đã sắp xếp
• Bước II – Thuật toán
for (i = 1; i <= n; i++){
 Trong dãy các phần tử từ a[i] đến a[n] tìm phần tử có giá trị nhỏ nhất, và giả sử
số nguyên nhỏ nhất tìm được là a[index_min] với i ≤ index_min ≤ n;
 Hoán đổi vị trí a[i] và a[index_min]; }
• Bước III – Cài đặt
Ví dụ: Mảng gồm 6 số nguyên 41
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Độ phức tạp của thuật toán
Cho 2 thuật toán cùng giải một bài toán cho trước, làm thế nào để xác định thuật toán nào tốt hơn?
• Khi nói đến hiệu quả của một thuật toán, ta quan tâm đến chi phí cần dùng để thực hiện nó:
1) Dễ hiểu, dễ cài đặt, dễ sửa đổi?
2) Thời gian sử dụng CPU? THỜI GIAN
3) Tài nguyên bộ nhớ? BỘ NHỚ
Trong giáo trình này ta đặc biệt quan tâm đến đánh giá thời gian cần thiết để thực hiện thuật toán
mà ta sẽ gọi là thời gian tính của thuật toán.
NGUYỄN KHÁNH PHƯƠNG 42
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Làm thế nào để đo được thời gian tính
• Mọi thuật toán đều thực hiện chuyển đổi đầu vào thành đầu ra: Thuật toán 5 3 1 2 sắp xếp 1 2 3 5 Đầu vào Đầu ra
• Thời gian tính của thuật toán phụ thuộc vào dữ liệu vào (kích thước tăng, thì thời gian tăng).
Định nghĩa. Ta gọi kích thước dữ liệu đầu vào (hay độ dài dữ liệu vào) là số bít
cần thiết để biểu diễn nó.
• Vậy, ta sẽ tìm cách đánh giá thời gian tính của thuật toán bởi một hàm của độ dài dữ liệu đầu vào.
• Tuy nhiên, trong một số trường hợp, kích thước dữ liệu đầu vào là như nhau, nhưng
thời gian tính lại rất khác nhau
• Ví dụ: Để tìm số nguyên tố đầu tiên có trong dãy: ta duyệt dãy từ trái sang phải
Dãy 1: 3 9 8 12 15 20 (thuật toán dừng ngay khi xét phần tử đầu tiên)
Dãy 2: 9 8 3 12 15 20 (thuật toán dừng khi xét phần tử thứ ba)
Dãy 3: 9 8 12 15 20 3 (thuật toán dừng khi xét phần tử cuối cùng)  3 loại thời gian tính 43
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Các loại thời gian tính
Thời gian tính tốt nhất (Best-case):
• T(n) : Thời gian tối thiểu cần thiết để thực hiện thuật toán với mọi bộ dữ liệu đầu vào kích thước n.
• Dùng với các thuật toán chậm chạy nhanh với một vài đầu vào.
Thời gian tính trung bình (Average-case):
• T(n) : Thời gian trung bình cần thiết để thực hiện thuật toán trên tập hữu hạn các đầu vào kích thước n.
• Rất hữu ích, nhưng khó xác định
Thời gian tính tồi nhất (Worst-case):
• T(n) : Thời gian nhiều nhất cần thiết để thực hiện thuật toán với mọi bộ dữ liệu đầu
vào kích thước n. Thời gian như vậy sẽ được gọi là thời gian tính tồi nhất của thuật
toán với đầu vào kích thước n. best case average case • Dễ xác định worst case 120 100 e 80
Có hai cách để đánh giá thời gian tính: Tim 60
• Từ thời gian chạy thực nghiệm 40 unning R 20 44
• Lý thuyết: khái niệm xấp xỉ tiệm cận 0 1000 2000 3000 4000 Input Size
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Phân tích thời gian tính của thuật toán bằng thời gian chạy thực nghiệm
Ta có thể đánh giá thuật toán bằng phương pháp thực nghiệm thông qua việc cài đặt
thuật toán, rồi chọn các bộ dữ liệu đầu vào thử nghiệm:
• Viết chương trình thực hiện thuật toán
• Chạy chương trình với các dữ liệu đầu vào kích thước khác nhau
• Sử dụng hàm clock( ) để đo thời gian chạy chương trình
• Vẽ đồ thị kết quả 9000 8000 7000 6000 ) 5000 (ms 4000 Time 3000 2000 1000 0 0 50 100
NGUYỄN KHÁNH PHƯƠNG 45
Bộ môn KHMT – ĐHBK HN Input Size
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Nhược điểm của việc đánh giá thời gian tính của thuật toán dựa vào thời gian
chạy thực nghiệm chương trình
• Bắc buộc phải cài đặt chương trình thì mới có thể đánh giá được thời gian
tính của thuật toán. Do phải cài đặt bằng một ngôn ngữ lập trình cụ thể nên
thuật toán sẽ chịu sự hạn chế của ngữ lập trình này. Đồng thời, hiệu quả của
thuật toán sẽ bị ảnh hưởng bởi trình độ của người cài đặt.
• Kết quả thu được sẽ không bao gồm thời gian chạy của những dữ liệu đầu
vào không được chạy thực nghiệm. Do vậy, cần chọn được các bộ dữ liệu
thử đặc trưng cho tất cả tập các dữ liệu vào của thuật toán  rất khó khăn và tốn nhiều chi phí.
• Để so sánh thời gian tính của hai thuật toán, cần phải chạy thực nghiệm hai
thuật toán trên cùng một máy, và sử dụng cùng một phần mềm.
 Do đó người ta đã tìm kiếm những phương pháp đánh giá thuật toán hình
thức hơn, ít phụ thuộc môi trường cũng như phần cứng hơn. Một phương
pháp như vậy là phương pháp đánh giá thuật toán theo hướng xấp xỉ tiệm cận
NGUYỄN KHÁNH PHƯƠNG 46
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Phân tích lý thuyết thời gian tính của thuật toán
• Sử dụng giả ngôn ngữ (pseudo-code) để mô tả thuật toán, thay vì tiến hành cài đặt thực sự
• Phân tích thời gian tính của thuật toán như là hàm của kích thước dữ
liệu đầu vào, n
• Phân tích tất cả các trường hợp có thể có của dữ liệu đầu vào
• Cho phép ta có thể đánh giá thời gian tính của thuật toán không bị phụ
thuộc vào phần cứng/phần mềm chạy chương trình (Thay đổi phần
cứng/phần mềm chỉ làm thay đổi thời gian chạy một lượng hằng số,
chứ không làm thay đổi tốc độ tăng của thời gian tính)
NGUYỄN KHÁNH PHƯƠNG 47
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung 1.1. Ví dụ mở đầu
1.2. Thuật toán và độ phức tạp
1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số kĩ thuật phân tích thuật toán
1.6. Giải công thức đệ quy
NGUYỄN KHÁNH PHƯƠNG 48
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.3. Kí hiệu tiệm cận (Asymptotic notation)
, O, o,  » Những kí hiệu này:
• Được sử dụng để mô tả thời gian tính của thuật toán, mô tả tốc độ tăng
của thời gian chạy phụ thuộc vào kích thước dữ liệu đầu vào.
• Được xác định đối với các hàm nhận giá trị nguyên không âm
• Dùng để so sánh tốc độ tăng của 2 hàm
Ví dụ: f(n) = (n2): mô tả tốc độ tăng của hàm f(n) và n2.
» Thay vì cố gắng tìm ra một công thức phức tạp để tính chính xác thời gian
tính của thuật toán, ta nói thời gian tính cỡ n2) [đọc là theta n2]: tức là,
thời gian tính tỉ lệ thuận với n2 cộng thêm các đa thức bậc thấp hơn
NGUYỄN KHÁNH PHƯƠNG 49
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 – Kí hiệu Theta
Đối với hàm g(n) cho trước, ta kí hiệu 𝚯(g(n)) là tập các hàm
(g(n)) = {f(n): tồn tại các hằng số c1, c2 và n0 sao cho
0  c1g(n)  f(n)  c2g(n), với mọi n n0 }
(tập tất cả các hàm có cùng tốc độ tăng với hàm g(n)).
• Hàm f(n) thuộc vào tập 𝚯(g(n)) nếu tồn tại hằng số dương c1 và c2 sao cho
nó bị “kẹp”giữa c1g(n) và c2g(n) với giá trị n đủ lớn • 𝑓 𝑛
𝚯(g(n)) tức là tồn tại hằng số c and c sao cho 1 2
c1g(n) ≤ f(n) ≤ c2g(n) với giá trị n đủ lớn.
Ta nói g(n) là đánh giá tiệm cận đúng cho f(n) và viết 𝑓 𝑛 𝚯(g(n))
• Khi ta nói một hàm là theta của hàm khác,
nghĩa là không có hàm nào đạt tới giá trị vô cùng nhanh hơn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
f(n) = (g(n))
c1, c2 , n0 >0 : n n0 , c1g(n)  f(n)  c2g(n)
Ví dụ 1: Chứng minh rằng 10n2 - 3n = 𝚯(n2)
• Ta cần chỉ ra với những giá trị nào n0, c1, c2 thì bất đẳng thức trong định
nghĩa của kí hiệu theta là đúng: 𝑐 𝑛 𝑓 𝑛 10𝑛
3𝑛 𝑐 𝑛 ∀n ≥ n0
• Gợi ý: lấy c1 nhỏ hơn hệ số của số hạng với số mũ cao nhất, và c2 lấy lớn hơn.
 Chọn: c1 = 1, c2 = 11, n0 = 1 thì ta có
n2 10n2 3n ≤ 11n2, với n ≥ 1.
 ∀n ≥ 1: 10n2 - 3n = 𝚯(n2)
• Chú ý: Với các hàm đa thức: để so sánh tốc độ tăng, ta cần nhìn vào số hạng có số mũ cao nhất 51
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
f(n) = (g(n))
c1, c2 , n0 >0 : n n0 , c1g(n)  f(n)  c2g(n)
Ví dụ 2: Chứng minh rằng 𝑓 𝑛 𝑛 3𝑛 𝚯 𝑛
Ta cần tìm n0, c và sao cho 1 c2 𝑐 𝑛 𝑓 𝑛 𝑛
3𝑛 𝑐 𝑛 ∀n ≥ n0
Chọn c1 = ¼, c2 = 1, và n0 = 7 ta có: 1 1 4 𝑛 𝑓 𝑛 2 𝑛 3𝑛 𝑛 ∀ 𝑛 7 ∀ 𝑛 7: 𝑛 3𝑛 𝚯 𝑛 52
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
f(n) = (g(n))
c1, c2 , n0 >0 : n n0 , c1g(n)  f(n)  c2g(n)
Ví dụ 3: Chứng minh rằng f(n) = 23n3 – 10 n2 log2n + 7n + 6 𝚯 𝑛
Ta phải tìm n0, c và sao cho 1 c2 𝑐 n3 𝑓 𝑛
23n3 – 10 n2 log2n + 7n + 6 𝑐 n3 với n n0
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
f(n) = (g(n))
c1, c2 , n0 >0 : n n0 , c1g(n)  f(n)  c2g(n)
Ví dụ 3: Chứng minh rằng f(n) = 23n3 – 10 n2 log2n + 7n + 6 𝚯 𝑛
f(n) = 23n3 – 10 n2 log2n + 7n + 6
f(n) = [23 – (10 log2 n)/n + 7/n2 + 6/n3]n3 Khi đó:
• n  10 : f(n)  (23 + 0 + 7/100 + 6/1000 )n3
= (23 + 0 + 0.07 + 0.006)n3
= 23.076 n3 < 24 n3
• n  10 : f(n)  (23 – log210 + 0 + 0 )n3 > (23 – log216)n3 =19n3 Ta có:
n  10: 19 n3  f(n)  24 n3
(n0 = 10, c1= 19, c2 = 24, g(n) = n3)
Do đó: f(n) = (n3)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
O – Kí hiệu O lớn (big Oh)
Đối với hàm g(n) cho trước, ta ký hiệu O(g(n)) là tập các hàm
O(g(n)) = {f(n): tồn tại các hằng số dương c n0 sao cho:
f(n)  cg(n) với mọi n n0 }
(tập tất cả các hàm có tốc độ tăng nhỏ hơn hoặc bằng tốc độ tăng của g(n)).
• Ta nói: g(n) là cận trên tiệm cận của f(n), và viết f(n) = O(g(n)).
f(n) =O(g(n)) tức là tồn tại hằng số c sao cho f(n) luôn ≤ cg(n) với mọi giá trị n đủ lớn.
O(g(n)) là tập các hàm đạt tới giá trị vô cùng
không nhanh hơn g(n). 55
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Minh họa hình học
O(g(n)) = {f(n) : hằng số dương c n0, sao cho
n n0, sao cho 0 f(n) cg(n) }f(n) = 2n+6
f(n) = 2n + 6
c g(n)=4n • Theo định nghĩa:
– Cần tìm hàm g(n) và hằng số
c n0 sao cho f(n) < cg(n) khi n > n0
g(n) = n, c = 4 và n0=3
f(n) là O(n) g(n)=n n 56
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ O lớn (Big-Oh)
O(g(n)) = {f(n) : hằng số dương c n0, sao cho
n n0, ta có 0 f(n) cg(n) }
• Ví dụ 1: Chứng minh rằng 2n + 10 = O(n)
f(n) = 2n+10, g(n) = n
 Cần tìm hằng số c n0 sao cho 2n + 10  cn với mọi n n0
 (c  2) n  10
n  10/(c  2)
 Chọn c = 3 và n0 = 10
• Ví dụ 2: Chứng minh rằng 7n - 2 = O(n)
f(n) = 7n-2, g(n) = n
 Cần tìm hằng số c n0 sao cho 7n - 2 cn với mọi n n0
 (7  c ) n ≤ 2
n ≤ 2/(7  c) 57
 Chọn c = 7 và n0 = 1
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Chú ý
• Các giá trị của các hằng số dương n0 và c không phải là duy nhất trong
chứng minh công thức tiệm cận
• Ví dụ: Chứng minh rằng 100n + 5 = O(n2)
– 100n + 5 ≤ 100n + n = 101n ≤ 101n2 ∀ n ≥ 5
n0 = 5 and c = 101 là các hằng số cần tìm
– 100n + 5 ≤ 100n + 5n = 105n ≤ 105n2 ∀ n ≥ 1
n0 = 1 and c = 105 cũng là các hằng số cần tìm
• Chỉ cần tìm các hằng số dương c n0 nào đó thỏa mãn bất đẳng thức trong
định nghĩa công thức tiệm cận 58
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ O lớn (Big-Oh)
O(g(n)) = {f(n) : hằng số dương c n0, sao cho
n n0, ta có 0 f(n) cg(n) }
• Ví dụ 3: Chứng minh rằng 3n3 + 20n2 + 5 = O(n3)
Cần tìm giá trị cho c n0 sao cho 3n3 + 20n2 + 5  cn3 với mọi n n0
Bất đẳng thức đúng với c = 4 và n0 = 21
• Ví dụ 4: Chứng minh rằng 3 log2n + 5 = O(log2n)
NGUYỄN KHÁNH PHƯƠNG 59
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ O lớn (Big-Oh)
O(g(n)) = {f(n) : hằng số dương c n0, sao cho
n n0, ta có 0 f(n) cg(n) } 1,000,000 n^2
• Ví dụ 5: hàm n2 không thuộc O(n)100,000 100n
n2  cn 10n – n
n c 10,000
– Bất đẳng thức trên không đúng vì 1,000
c phải là hằng số 100 10 1 1 10 100 1,000 n 60
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 O lớn và tốc độ tăng
• Kí hiệu O lớn cho cận trên tốc độ tăng của một hàm
• Khi ta nói “f(n) là O(g(n))” nghĩa là tốc độ tăng của hàm f(n) không
lớn hơn tốc độ tăng của hàm g(n)
• Ta có thể dùng kí hiệu O lớn để sắp xếp các hàm theo tốc độ tăng của chúng
f(n) là O(g(n))
g(n) là O(f(n))
g(n) có tốc độ tăng lớn hơn f(n) Yes No
g(n) có tốc độ tăng nhỏ hơn f(n) ? ?
g(n) và f(n) cùng tốc độ tăng ? ?
NGUYỄN KHÁNH PHƯƠNG 61
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Các biểu thức sai f ( ) n  ( O ( g ) n X f ( ) n
X (O (g )n 62
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ O lớn (Big-Oh)
f(n) = 50n3 + 20n + 4 là O(n3)
– Cũng đúng khi nói f(n) là O(n3+n)
• Không hữu ích, vì n3 có tốc độ tăng lớn hơn rất nhiều so với n, khi n lớn
– Cũng đúng khi nói f(n) là O(n5)
• OK, nhưng g(n) nên có tốc độ tăng càng gần với tốc độ tăng của
f(n) càng tốt, thì đánh giá thời gian tính mới có giá trị
• 3log(n) + log (log (n)) = O( ? )
• Quy tắc đơn giản: Bỏ qua các số hạng có
số mũ thấp hơn và các hằng số 63
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Một số quy tắc O lớn • Nếu 2
f(n) là đa thức bậc d:
f nd
a a n a n ... a n 0 1 2 d
thì f(n) = O(nd), tức là,
1. Bỏ qua các số hạng có số mũ thấp hơn d
2. Bỏ qua các hằng số
Ví dụ: 3n3 + 20n2 + 5 = O(n3)
• Nếu f(n) = O(nk) thì f(n) = O(np) với ∀ p > k
Ví dụ: 2n2 = O(n2) thì 2n2 = O(n3)
Khi đánh giá tiệm cận f(n) = O(g(n)), ta nên tìm hàm g(n) có tốc độ tăng càng chậm càng tốt
• Sử dụng lớp các hàm có tốc độ tăng nhỏ nhất có thể
Ví dụ: Nói “2n = O(n)” tốt hơn là nói “2n = O(n2)”
• Sử dụng lớp các hàm đơn giản nhất có thể
Ví dụ: Nói “3n + 5 = O(n)” thay vì nói “3n + 5 = O(3n)” 64
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ O lớn
• Tất cả các hàm sau đều là O(n):
n, 3n, 61n + 5, 22n – 5, …
• Tất cả các hàm sau đều là O(n2):
n2, 9 n2, 18 n2+ 4n – 53, …
• Tất cả các hàm sau đều là O(n log n):
n(log n), 5n(log 99n), 18 + (4n – 2)(log (5n + 3)), …
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ω- kí hiệu Omega
• Đối với hàm g(n) cho trước, ta kí hiệu (g(n)) là tập các hàm
(g(n)) = {f(n): tồn tại các hằng số dương c n0 sao cho:
cg(n)  f(n) với mọi n n0 }
(tập tất cả các hàm có tốc độ tăng lớn hơn hoặc bằng tốc độ tăng của g(n)).
• Ta nói: g(n) là cận dưới tiệm cận của hàm, và viết f(n) = (g(n)).
f(n) = (g(n)) nghĩa là tồn tại hằng số c sao cho f(n) luôn
cg(n) với giá trị n đủ lớn.
(g(n)) là tập các hàm đạt tới giá trị vô cùng không chậm hơn g(n)
f(n) = (g(n)) f(n) = (g(n))
(g(n))  (g(n)).
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ Kí hiệu Omega
(g(n)) = {f(n) :  hằng số dương c n0, sao cho
n n0, ta có 0  cg(n)  f(n)}
• Ví dụ 1: Chứng minh rằng 5n2 = (n)
Cần tìm c n0 sao cho cn  5n2 với n n0
Bất đẳng thức đúng với c = 1 và n0 = 1 Nhận xét:
• Nếu f(n) = (nk) thì f(n) = (np) với ∀ p < k.
• Khi đánh giá tiệm cận f(n) = (g(n)), ta cần tìm hàm g(n) có tốc độ tăng càng nhanh càng tốt
• Ví dụ 2: Chứng minh 𝑛 = (lg n)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Kí hiệu tiệm cận trong các đẳng thức
Kí hiệu tiệm cận còn được dùng để thay thế các biểu thức chứa các toán
hạng với tốc độ tăng chậm. Ví dụ:
4n3 + 3n2 + 2n + 1 = 4n3 + 3n2 + (n)
= 4n3 + (n2) = (n3)
Trong các đẳng thức, (f(n)) thay thế cho một hàm nào đó g(n)  (f(n))
– Trong ví dụ trên, ta dùng (n2) thay thế cho 3n2 + 2n + 1
NGUYỄN KHÁNH PHƯƠNG 68
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Các kí hiệu tiệm cận
Đồ thị minh họa cho các kí hiệu tiệm cận 𝚯, O, và Ω
Định lý: Đối với hai hàm bất kỳ f(n) và g(n), ta có 𝑓 𝑛 𝚯(g(n)) khi và chỉ khi 𝑓 𝑛
𝑂(g(n)) và 𝑓 𝑛 Ω(g(n)) 69
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Định lý: Đối với hai hàm bất kỳ f(n) và g(n), ta có 𝑓 𝑛 𝚯(g(n)) khi và chỉ khi 𝑓 𝑛
𝑂(g(n)) và 𝑓 𝑛 Ω(g(n))
Ví dụ 1: Chứng minh f(n) = 5n2 𝚯 𝑛 Vì: • 5n2 O 𝑛2
f(n) = O(g(n)) nếu tồn tại hằng số c > 0 và hằng số nguyên n0  1 sao cho f(n) ≤
cg(n) với n n0
chọn c = 5 và n0 = 1 • 5n2 Ω(n2)
f(n) = (g(n)) nếu tồn tại hằng số c > 0 và hằng số nguyên n0  1 sao cho f(n) 
cg(n) với n n0
Chọn c = 5 và n0 = 1
Do đó: f(n) = (n2) 𝑓 𝑛 𝚯(g(n))
f(n) = O(g(n))
f(n) = (g(n)) 70
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Định lý: Đối với hai hàm bất kỳ f(n) và g(n), ta có 𝑓 𝑛 𝚯(g(n)) khi và chỉ khi 𝑓 𝑛
𝑂(g(n)) và 𝑓 𝑛 Ω(g(n))
Ví dụ 2: Chứng minh f(n) = 3n2 – 2n + 5 𝚯 𝑛 Vì:
3n2 – 2n + 5 O 𝑛2
f(n) = O(g(n)) nếu tồn tại hằng số c > 0 và số nguyên n0  1 sao cho
f(n) ≤ cg(n) với n n0
 Chọn c = ? và n0 = ?
3n2 – 2n + 5 Ω(n2)
f(n) = (g(n)) nếu tồn tại hằng số c > 0 và số nguyên n0  1 sao cho
f(n)  cg(n) với n n0
 Chọn c = ? và n0 = ?
Do đó: f(n) = (n2) 𝑓 𝑛 𝚯(g(n))
f(n) = O(g(n)) 71
f(n) = (g(n))
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Bài tập 1
Chứng minh: 100n + 5 ≠ (n2)
Giải: Chứng minh bằng phản chứng
– Giả sử: 100n + 5 = (n2)
  c, n0 sao cho: 0  cn2  100n + 5
– Ta có: 100n + 5  100n + 5n = 105n n  1
– Do đó: cn2  105n n(cn – 105)  0
– Vì n > 0  cn – 105  0  n  105/c
bất đẳng thức trên không đúng vì c phải là hằng số 72
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Bài tập 2
Chứng minh: n ≠ (n2)
Giải: Chứng minh bằng phản chứng
– Giả sử: n = (n2)
  c1, c2, n0 sao cho: c1 n2 ≤ n c2 n2  n n0 n ≤ 1/c1
Bất đẳng thức trên không đúng vì c1 phải là hằng số 73
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Bài tập 3:Chứng minh
a) 6n3 ≠ (n2)
Giải: Chứng minh bằng phản chứng
– Giả sử: 6n3 = (n2)
  c1, c2, n0 sao cho: c1 n2 ≤ 6n3 ≤ c2 n2  n n0
n c2/6  n n0
Bất đẳng thức trên không đúng vì c2 phải là hằng số
b) n ≠ (log2n) Giải:
NGUYỄN KHÁNH PHƯƠNG 74
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Cách nói về thời gian tính
• Nói “Thời gian tính là O(f(n))”, hiểu là đánh giá trong tình huống tồi nhất (worst
case) là O(f(n)) (nghĩa là, không tồi hơn c*f(n) với n lớn, vì kí hiệu O lớn cho ta cận
trên). [Thường nói: “Đánh giá thời gian tính trong tình huống tồi nhất là O(f(n))”]
• Nghĩa là thời gian tính trong tình huống tồi nhất được xác định bởi một hàm nào
đó g(n) (f(n))
• Nói “Thời gian tính là  (f(n))”, hiểu là đánh giá trong tình huống tốt nhất (best
case) là (f(n)) (nghĩa là, không tốt hơn c*f(n) với n lớn, vì kí hiệu Omega cho ta
cận dưới). [Thường nói: “Đánh giá thời gian tính trong tình huống tốt nhất là (f(n))”]
• Nghĩa là thời gian tính trong tình huống tốt nhất được xác định bởi một hàm nào
đó g(n)   (f(n))
NGUYỄN KHÁNH PHƯƠNG 75
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Thời gian tính trong tình huống tồi nhất
• Khi phân tích một thuật toán
– Chỉ quan tâm đến các trường hợp thuật toán chạy
• Tốn thời gian chạy nhất
(tính cận trên cho thời gian tính của thuật toán)
– Nếu thuật toán có thể giải trong thời gian cỡ hàm f(n)
• Thì trường hợp tồi nhất, thời gian chạy không thể lớn hơn c*f(n)
• Hữu ích khi thuật toán áp dụng cho trường hợp
• Cần biết cận trên cho thuật toán • Ví dụ:
– Các thuật toán áp dụng chạy trong nhà máy điện hạt nhân.
NGUYỄN KHÁNH PHƯƠNG 76
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Thời gian tính trong tình huống tốt nhất
• Khi ta phân tích một thuật toán
– Chỉ quan tâm đến các trường hợp thuật toán chạy • Ít thời gian nhất
(tính cận dưới của thời gian chạy)
NGUYỄN KHÁNH PHƯƠNG 77
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Thời gian tính trong tình huống trung bình
• Nếu thuật toán phải sử dụng nhiều lần
– hữu ích khi tính đượng thời gian chạy trung bình của thuật toán với kích
thước dữ liệu đầu vào là n
• Đánh giá thời gian tính trung bình khó hơn với việc đánh giá thời gian tính tồi/tốt nhất
– Cần có thông tin về phân phối của dữ liệu dữ liệu
Ví dụ: Thuật toán sắp xếp chèn (Insertion sorting) có thời gian trung bình cỡ n2
NGUYỄN KHÁNH PHƯƠNG 78
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Một số lớp thuật toán cơ bản – Hằng số  O(1)
– Logarithmic  O(log2n)
– Tuyến tính  O(n)
– N-Log-N  O(nlog2n)
– Bình phương (Quadratic)  O(n2)
– Bậc 3 (Cubic)  O(n3)
– Hàm mũ (exponential)  O(an) (a > 1)
– Đa thức (polynomial): O(nk) (k ≥1)
• Thuật toán có đánh giá thời gian tính là O(nk) được gọi là thuật toán
thời gian tính đa thức (hay vắn tắt: thuật toán đa thức)
• Thuật toán đa thức được coi là thuật toán hiệu quả.
• Các thuật toán với thời gian tính hàm mũ là không hiệu quả.
Sau đây, ta sẽ lấy một số ví dụ về phân loại các hàm 79
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Một số hàm cơ bản
Những hàm nào trong số những hàm sau giống nhau hơn? n1000 n2 2n Đa thức (polynomial) 80
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Một số hàm cơ bản
Những hàm nào trong số những hàm sau giống nhau hơn? 1000n2 3n2 2n3 Hàm bậc 2 (quadratic) 81
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Tốc độ tăng của một số hàm cơ bản n logn n
nlogn n2 n3 2n 4 2 4 8 16 64 16 8 3 8 24 64 512 256 16 4 16 64 256 4,096 65,536 32 5 32 160 1,024 32,768 4,294,967,296 64 6 64 384 4,094 262,144 1.84 * 1019 128 7 128 896 16,384 2,097,152 3.40 * 1038 256 8 256 2,048 65,536 16,777,216 1.15 * 1077 512 9 512 4,608 262,144 134,217,728 1.34 * 10154 1024 10 1,024 10,240 1,048,576 1,073,741,824 1.79 * 10308 82
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Phân loại thời gian tính của thuật toán
• Thời gian để giải một bộ dữ liệu đầu vào của
– Thuật toán có thời gian tính tuyến tính (Linear Algorithm):
• Không bao giờ lớn hơn c*n
– Thuật toán có thời gian tính là hàm đa thức bậc 2 (Quadratic Algorithm):
• Không bao giờ lớn hơn c*n2
– Thuật toán có thời gian tính là hàm đa thức bậc ba (Cubic Algorithm):
• Không bao giờ lớn hơn c*n3
– Thuật toán có thời gian tính đa thức (Polynomial Algorithm)
• Không bao giờ lớn hơn nk
– Thuật toán có thời gian tính hàm mũ (Exponential Algorithm)
• Không bao giờ lớn hơn cn
với c k là các hằng số tương ứng 83
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Cận trên và cận dưới Upper Bound and Lower Bound
Định nghĩa (Upper Bound). Cho bài toán P, ta nói cận trên cho thời gian
tính của P O(g(n)) nếu để giải P tồn tại thuật toán giải với thời gian tính là
O(g(n)) .
Định nghĩa (Lower Bound). Cho bài toán P, ta nói cận dưới cho thời gian
tính của P là (g(n)) nếu mọi thuật toán giải P đều có thời gian tính là
(g(n)) .
Định nghĩa. Cho bài toán P, ta nói thời gian tính của P là (g(n)) nếu P
cận trên là O(g(n)) và cận dưới là (g(n)) .
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Bài toán dễ giải, khó giải
và không giải được
• Một bài toán được gọi là dễ giải (tractable) nếu như nó có thể giải được nhờ thuật
toán đa thức. Bài toán có cận trên cho thời gian tính là đa thức.
Ví dụ: bài toán dãy con lớn nhất, bài toán sắp xếp dãy n số, ....
• Một bài toán được gọi là khó giải (intractable) nếu như nó không thể giải được bởi
thuật toán đa thức. Bài toán có cận dưới cho thời gian tính là hàm mũ.
Ví dụ: Bài toán liệt kê các hoán vị của n số, các xâu nhị phân độ dài n, ...
• Một dạng bài toán nữa cũng được coi là khó giải: Đó là những bài toán cho đến thời
điểm hiện tại vẫn chưa tìm được thuật toán đa thức để giải nó.
Ví dụ: Bài toán cái túi, Bài toán người du lịch,…
• Một bài toán được gọi là không giải được (nonsolvable) nếu như không tồn tại thuật toán để giải nó..
Ví dụ: Bài toán về tính dừng, Bài toán về nghiệm nguyên của đa thức
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Sự tương tự giữa so sánh các hàm số và so sánh số
Chú ý rằng mối quan hệ giữa các hàm số cũng giống như mỗi quan hệ
“<, >, =” giữa các số
f g a b
f (n) = O(g(n))  a b
f (n) = (g(n))  a b
f (n) = (g(n))  a = b
f (n) = o(g(n))  a < b
f (n) = (g(n))  a > b 86
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Nhắc lại một số khái niệm toán học  Hàm mũ:
a(b+c) = abac
abc = (ab)c
ab /ac = a(b-c)
b = a log b a
bc = a c*log b a  Hàm Logarit:
x = log a là số mũ log a b b a b cho a = bx.
log (ab)  log a  log b c c c n
log a nlog a Logarit tự nhiên: ln b b a = log a e log a c Logarit bậc 2: lg log a a = log a b log 2 b c log 1
( / a)  log a b b lg2a = (lg a)2 1 log a  lg lg b a = lg (lg a) log b a log c log a b b ac 87
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Hàm logarit và hàm mũ
• Nếu cơ số của hàm logarit thay đổi giá trị từ hằng số này sang
hằng số khác, thì giá trị của hàm bị thay đổi một lượng hằng số.
Ví dụ: log10 n * log210 = log2 n.
– Do đó, trong ký hiệu tiệm cận cơ số của log là không quan trọng:
O(lg n) = O(ln n) = O(log n)
• Giá trị của hai hàm mũ khác nhau cơ số khác nhau một lượng cỡ
hàm mũ (chứ không phải một lượng là hằng số)
Ví dụ: 2n = (2/3)n*3n. 88
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Bài tập
• Sắp xếp các hàm sau theo thứ tự tốc độ tăng dần
1. nlog2n 2. log2n3 3. n2 4. n2/5
5. 𝟐𝒍𝒐𝒈𝟐𝒏
6. log2(log2n)
7. Sqr(log2n) Sqr: square (bình phương)
Sqrt: square root (căn bậc 2) 89
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Cách nhớ các kí hiệu Theta
f(n) = (g(n))
f(n) ≈ c g(n) Big Oh
f(n) = O(g(n))
f(n) ≤ c g(n) Big Omega
f(n) = Ω(g(n))
f(n) ≥ c g(n) 90
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Các tính chất
• Transitivity (truyền ứng)
f(n) = (g(n)) & g(n) = (h(n))  f(n) = (h(n))
f(n) = O(g(n)) & g(n) = O(h(n))  f(n) = O(h(n))
f(n) = (g(n)) & g(n) = (h(n))  f(n) = (h(n)) • Reflexivity (phản xạ)
f(n) = (f(n))
f(n) = O(g(n))
f(n) = (g(n)) • Symmetry (đối xứng)
f(n) = (g(n)) if and only if g(n) = (f(n))
• Transpose Symmetry (Đối xứng chuyển vị)
f(n) = O(g(n)) if and only if g(n) = (f(n))
Ví dụ: A = 5n2 + 100n,
B= 3n2 + 2 . Chứng minh A  (B)
Giải: A  (n2), n2  (B)  A  (B) 91
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Liên hệ với khái niệm giới hạn
lim [f(n) / g(n)] <   f(n)  O(g(n)) n
0 < lim [f(n) / g(n)] <   f(n)  (g(n)) n
0 < lim [f(n) / g(n)]  f(n) (g(n)) n
lim [f(n) / g(n)] không xác định không thể nói gì n Chú ý: f (n)
f(n) = n sin n; g(n) = n. Mặc dù lim
 limsin n không tồn tại, nhưng rõ ràng
n g(n) n
n sin n = O(n).
Ví dụ: Biểu diễn hàm A bằng kí hiệu tiệm cận sử dụng hàm B. A B log3(n2)
log2(n3) A  (B)
logba = logca / logcb; A = 2lgn / lg3, B = 3lgn, A/B =2/(3lg3)  A  (B) 92
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Bài tập Chứng minh
1) 3n2 – 100n + 6 = O(n2)
2) 3n2 – 100n + 6 = O(n3)
3) 3n2 – 100n + 6 ≠ O(n)
4) 3n2 – 100n + 6 = Ω(n2)
5) 3n2 – 100n + 6 ≠ Ω(n3)
6) 3n2 – 100n + 6 = Ω(n)
7) 3n2 – 100n + 6 = 𝚯(n2)
8) 3n2 – 100n + 6 ≠ 𝚯(n3)
9) 3n2 – 100n + 6 ≠ 𝚯(n) 93
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Chú ý •
Giả sử có 2 thuật toán: Thời gian chạy •
Thuật toán A có thời gian chạy 30000n
Thuật toán B có thời gian chạy 3n2 A
Theo đánh giá tiệm cận, thuật toán A tốt hơn thuật toán B •
Tuy nhiên, nếu kích thước dữ liệu của bài toán luôn
nhỏ hơn 10000, thì thuật toán B lại tốt (nhanh) hơn A B 10000 Kích thước dữ liệu đầu vào
NGUYỄN KHÁNH PHƯƠNG 94
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung 1.1. Ví dụ mở đầu
1.2. Thuật toán và độ phức tạp 1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số kĩ thuật phân tích thuật toán
1.6. Giải công thức đệ quy 95
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.4. Giả ngôn ngữ (Pseudocode)
• Để mô tả thuật toán, ta có thể sử dụng
một ngôn ngữ lập trình nào đó. Tuy
nhiên, điều đó có thể làm cho việc mô tả
thuật toán trở nên phức tạp và khó nắm
bắt. Do đó, để mô tả thuật toán, người ta
thường sử dụng giả ngôn ngữ (pseudo Ví dụ: tìm phần tử lớn nhất trong mảng language), cho phép:
Function arrayMax(A, n)
– Mô tả thuật toán bằng ngôn ngữ đời thường
//Input: mảng A gồm n số nguyên
– Sử dụng các cấu trúc câu lệnh tương //Output: phần tử lớn nhất của mảng A
tự như của ngôn ngữ lập trình. begin
• Dưới đây ta liệt kê một số câu lệnh currentMax  A[0]
chính được sử dụng trong giáo trình để mô tả thuật toán.
for i  1 to n  1
if (A[i]  currentMax) then
currentMax A[i] endif; endfor;
return currentMax; end; 96
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 1.4. Pseudocode • Khai báo biến integer x, y; real u, v; boolean a, b; char c, d; datatype x; • Lệnh gán x = biểu thức; hoặc x ← biểu thức;
Ví dụ: x ← 1+4; y=a*y+2; 97
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 1.4. Pseudocode
Cấu trúc điều khiển:
if điều_kiện then dãy các câu lệnh else dãy các câu lệnh endif;
while điều_kiện do dãy các câu lệnh endwhile; repeat dãy các câu lệnh until condition;
NGUYỄN KHÁNH PHƯƠNG 98
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 1.4. Pseudocode
Cấu trúc điều khiển:
for i=n1 to n2 [step d] dãy các câu lệnh endfor; Case
điều_kiện_1: câu_lệnh_1;
điều_kiện_2: câu_lệnh_2; . . .
điều_kiện_n: câu_lệnh_n;
endcase;
NGUYỄN KHÁNH PHƯƠNG 99
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 1.4. Pseudocode • Vào/ra:
read(X); /* X là biến */ print(data);
hoặc print(thông báo);
Ví dụ: tìm phần tử lớn nhất trong mảng
Hàm và thủ tục:
Function name(arguments)
Function arrayMax(A, n) begin
//Input: mảng A gồm n số nguyên khai báo biến;
//Output: phần tử lớn nhất của mảng A các câu lệnh trong hàm; begin return (value); currentMax  A[0] end;
for i  1 to n  1
if (A[i]  currentMax) then
Procedure name(arguments)
currentMax A[i] begin endif; khai báo biến; endfor;
các câu lệnh trong thủ tục;
return currentMax; end; end; 100
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 1.4. Pseudocode
Ví dụ 2: hoán đổi giá trị của hai biến Procedure swap(x, y) begin temp=x; x = y; y = temp; end;
Hoặc có thể viết đơn giản như sau: Procedure swap(x, y) temp=x; x = y; y = temp; 101
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Pseudocode: Ví dụ 3
Đề bài: Tìm số nguyên tố nhỏ nhất lớn hơn một số nguyên dương n cho trước
• Đầu tiên ta viết hàm Is_Prime kiểm tra xem một số nguyên dương m có phải là số
nguyên tố hay không. Xây dựng hàm này như sau:
– Nếu m = a*b với 1 < a, b < m, thì một trong hai số a b có giá trị không thể
vượt quá 𝑚. Do đó, số nguyên tố lớn nhất nhỏ hơn m sẽ có giá trị không vượt
quá 𝑚  m là số nguyên tố nếu nó không chia hết cho bất kì số nguyên nào trong khoảng [2, 𝑚].
• Sau đó, để tìm số nguyên tố nhỏ nhất lớn hơn n như sau:
– Ta dùng hàm Is_Prime để xét lần lượt các số lớn hơn n là: n+1, n+2, n+3,…
xem có số nào là số nguyên tố hay không. Nếu tìm được thì thuật toán kết thúc
và trả về số nguyên tố vừa tìm được.
NGUYỄN KHÁNH PHƯƠNG 102
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Pseudocode: Ví dụ 3
Thuật toán kiểm tra số nguyên dương có phải là số nguyên tố hay không:
Input: Số nguyên dương m. •
Output: true nếu m là số nguyên tố, false nếu ngược lại. Function Is_prime(m) begin i = 2;
while (i*i <= m) and (m mod i ≠ 0) do i=i+1; endwhile; Is_prime = i > sqrt(m); end Is_Prime;
Thuật toán tìm số nguyên tố nhỏ nhất mà lớn hơn số nguyên dương n:
• Thuật toán sử dụng hàm Is_prime như là 1 thủ tục con.
Input: Số nguyên dương n.
Output: m là số nguyên tố nhỏ nhất mà lớn hơn số nguyên dương n. procedure Lagre_Prime(n) begin m = n+1; while not Is_prime(m) do m=m+1; endwhile; 103 end;
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung 1.1. Ví dụ mở đầu
1.2. Thuật toán và độ phức tạp 1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số kĩ thuật phân tích thuật toán
1.6. Giải công thức đệ quy
NGUYỄN KHÁNH PHƯƠNG 104
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Tính toán thời gian tính của thuật toán
• Đánh giá qua thời gian chạy thực nghiệm:
– Cần: cài đặt chương trình thực thi thuật toán, sau đó chạy chương trình và đo thời gian chạy. – Nhược điểm:
• Bắc buộc phải cài đặt thuật toán
• Kết quả thu được sẽ không bao gồm thời gian chạy của những dữ liệu đầu vào không
được chạy thực nghiệm. Do vậy, cần chọn được các bộ dữ liệu thử đặc trưng cho tất
cả tập các dữ liệu vào của thuật toán  rất khó khăn và tốn nhiều chi phí.
• Để so sánh thời gian tính của hai thuật toán, cần phải chạy thực nghiệm hai thuật
toán trên cùng một máy, và sử dụng cùng một phần mềm.
 Ta cần đánh giá thuật toán theo hướng xấp xỉ tiệm cận
• Đánh giá thời gian chạy theo hướng xấp xỉ tiệm cận:
– Sử dụng giả ngôn ngữ để mô tả thuật toán, thay vì cài đặt thực sự
– Phân tích thời gian tính như làm hàm của dữ liệu đầu vào, n
– Đánh giá trên tất cả các bộ dữ liệu vào có thể có của bài toán
– Cho phép ta đánh giá được thời gian tính của thuật toán độc lập với phần cứng và
phần mềm cần sử dụng để cài đặt thuật toán.
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Phép toán cơ bản
• Để đo thời gian tính bằng phương pháp đánh giá tiệm cận, ta sẽ đếm
số phép toán cơ bản mà thuật toán phải thực hiện
là phép toán có thể thực hiện với thời gian bị chặn bở một hằng số
không phụ thuộc vào kích thước dữ liệu vào.
• Ví dụ về các phép toán cơ bản: – Tính biểu thức x2+ey
– Phép gán giá trị cho một biến cnt  cnt+1 – Đánh chỉ số mảng A[5] – Gọi 1 phương thức mySort(A,n)
– Lệnh trả về giá trị từ 1 phương thức return(cnt) 106
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Phân tích độ phức tạp của thuật toán: Các kĩ thuật cơ bản 1. Cấu trúc tuần tự
Thời gian tính của chương trình P; Q”,với P và Q là hai đoạn chương trình thực thi
một thuật toán, P thực hiện trước, rồi đến Q là
Time(P; Q) = Time(P) + Time(Q) ,
hoặc ta có thể dùng kí hiệu tiệm cận theta:
Time(P; Q) = (max(Time(P), Time(Q)).
với Time(P), Time(Q) là thời gian tính của P và Q. 2. Vòng lặp FOR
for i =1 to m do P(i);
Giả sử thời gian thực hiện P(i) là t(i), khi đó thời gian thực hiện vòng lặp for là ∑ 𝑡 𝑖
3. Vòng lặp lồng nhau
for i =1 to n do
for j =1 to m do P(j);
Giả sử thời gian thực hiện P(j) là t(j), khi đó thời gian thực hiện vòng lặp lồng nhau này là:
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Phân tích độ phức tạp của thuật toán: Các kĩ thuật cơ bản 4. If/Else
if (điều_kiện) then P; else Q; endif;
Thời gian thực hiện câu lệnh if/else
= thời gian kiểm tra (điều_kiện) + max (Time(P), Time (Q))
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ
Case1: for (i=0; ifor (j=0; jO(n2) k++; Case 2: for (i=0; ik++; for (i=0; iO(n2) for (j=0; jk++;
Case 3: for (int i=0; ifor (int j=0; jint k+=1; O(n2)
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Phân tích độ phức tạp của thuật toán: Các kĩ thuật cơ bản 5. Vòng lặp while/repeat
• Cần xác định một hàm của các biến trong vòng lặp sao cho hàm này có giá
trị giảm dần trong quá trình lặp. Khi đó:
– Để chứng minh tính kết thúc của vòng lặp ta chỉ cần chỉ ra giá trị của
hàm là số nguyên dương.
– Còn để xác định số lần lặp ta cần phải khảo sát xem giá trị của hàm giảm như thế nào.
• Việc phân tích vòng lặp Repeat được tiến hành tương tự như phân tích vòng lặp While.
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Câu lệnh đặc trưng
Định nghĩa. Câu lệnh đặc trưng là câu lệnh được thực hiện
thường xuyên ít nhất là cũng như bất kỳ câu lệnh nào trong thuật toán.
• Nếu giả thiết thời gian thực hiện mỗi câu lệnh là bị chặn bởi
hằng số thì thời gian tính của thuật toán sẽ cùng cỡ với số
lần thực hiện câu lệnh đặc trưng
• => Để đánh giá thời gian tính có thể đếm số lần thực hiện câu lệnh đặc trưng
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 1: Tính dãy Fibonacci function Fibrec(n)
• Dãy Fibonacci (0, 1, 1, 2, 3,
if n <2 then return n; 5, 8, 13, 21, 34….)
else return Fibrec(n-1)+Fibrec(n-2);f0=0; – f1=1; function Fibiter(n)
fn= fn-1 + fn-2 i=0; j=1; for k=1 to n do j=i + j; Câu lệnh đặc trưng i=j – i;
• Số lần thực hiện câu lệnh đặc trưng là n  Thời gian chạy return j; Fibiter là O(n) n 10 20 30 50 100 Fibrec 8ms 1sec 2min 21days 109years Fibiter 0.17ms 0.33ms 0.5ms 0.75ms 1.5ms 112
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 2: Bài toán dãy con lớn nhất
Cho mảng số nguyên A1, A2, …, AN, tìm giá trị lớn nhất của ∑ 𝐴
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Thuật toán 1. Duyệt toàn bộ (Brute force) int maxSum = 0; for (int i=0; i for (int j=i; j int sum = 0;
for (int k=i; k<=j; k++) sum += a[k]; if (sum > maxSum) maxSum = sum; } }
Chọn câu lệnh đặc trưng là sum+=a[k]
 Thời gian tính của thuật toán: O(n3)
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Thuật toán 2. Duyệt toàn bộ có cải tiến int maxSum = a[0]; for (int i=0; i int sum = 0; for (int j=i; j sum += a[j]; if (sum > maxSum) maxSum = sum; O(n2) } }
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Thuật toán 3. Đệ quy O(n) O(n) T(n/2) T(n/2)
T(n) = 2T(n/2)+O(n)
 T(n) = O(nlogn)
Giải công thức đệ quy này thế nào ? (xem mục 1.6.) 116
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Nhắc lại một số kiến thức N
S (N )  1 2  N  i N 1 (  N) / 2 i1
• Tổng bình phương: N 2 N(N  )( 1 2N  ) 1 3 Ni   large for N i 1  6 3 N k 1  • Tổng mũ:  k N i large for k and N  -1 i 1  | k 1| N N 1  i A 1 • Dãy:  A i0 A 1
– Trường hợp đặc biệt A = 2
• 20 + 21 + 22 + … + 2N = 2N+1 - 1
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 3
• Đưa ra đánh giá tiệm cận O lớn cho thời gian tính T(n) của đoạn chương trình sau:
for (int i = 1; i<=n; i++)
for (int j = 1; j<= i*i*i; j++)
for (int k = 1; k<=n; k++) x = x + 1; • Giải: 3 n i n
T(n)  1
i1 j 1 k 1 3 3 n i n i n
  n   n(1)   3 ni i1 j 1 i1 j 1 i1 n n n
n 3i n 3 n  4 n 1  5 n i1 i1 i1
So T(n) = O(n5).
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 4
Đưa ra đánh giá tiệm cận O lớn cho thời gian tính T(n) của đoạn chương trình sau: a) int x = 0;
for (int i = 1; i <=n; i *= 2) x=x+1; • Giải:
Vòng lặp for thực hiện log2n lần, do đó T(n) = O(log2n). b) int x = 0;
for (int i = n; i > 0; i /= 2) x=x+1; • Giải:
Vòng lặp for thực hiện …..
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 5
Đưa ra đánh giá tiệm cận O lớn cho thời gian tính T(n) của đoạn chương trình sau: int n; if (n<1000) for (int i=0; i for (int j=0; j for (int k=0; k
cout << "Hello\n"; else for (int j=0; j for (int k=0; k
cout << "world!\n"; Giải:
T(n) hằng số khi n <1000. T(n) = O(n2).
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 6: Thuật toán số nguyên tố
• Thuật toán kiểm tra xem số nguyên dương m > 1 có phải là số nguyên tố hay không.
Algorithm PRIME(m)
for i=2 to sqrt(m) do
if m mod i = 0 then return FALSE return YES
• Thời gian tính: T(n) = O( ). Thuật toán đa thức?
• Kích thước dữ liệu vào: n  log2  m  2n
T(n) = O(m1/2) = O(2n/2). Thời gian tính hàm mũ!
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Nội dung 1.1. Ví dụ mở đầu
1.2. Thuật toán và độ phức tạp 1.3. Kí hiệu tiệm cận
1.4. Giả ngôn ngữ (Pseudo code)
1.5. Một số kĩ thuật phân tích thuật toán
1.6. Giải công thức đệ quy
Độ phức tạp tính toán của các thuật toán được xây dựng dưới dạng công thức đệ
quy của số lượng thao tác trong thuật toán.
Ví dụ: Trong mục trước, ta học thuật toán đệ quy giải bài toán tổng dãy con lớn
nhất có độ phức tạp là T(n) = 2T(n/2) + O(n).
Giải công thức đệ quy này ta thu được T(n) = O(nlogn) 122
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy Định nghĩa:
Công thức đệ quy cho dãy số {a } là công thức biểu diễn a dưới dạng n n
một hoặc nhiều thành phần trước nó trong dãy a0, a1, …, an-1 với mọi số
nguyên n n0 , n0 là số nguyên không âm
Một dãy số được gọi là một lời giải của công thức đệ quy nếu các thành phần
trong dãy số đó thỏa mãn công thức đệ quy.
Ví dụ: Xét công thức đệ quy Dãy số = a = 2a a n+1?? n n
n-1 – an-2 với n = 2, 3, 4, …
• Dãy số a =3n là lời giải của công thức đệ quy đã cho? n
Với n  2 ta có: 2an-1 – an-2 = 2(3(n – 1)) – 3(n – 2) = 3n = an
Do đó, dãy số a =3n là lời giải của công thức đệ quy đã cho n
• Dãy số a =5 cũng là lời giải của công thức đệ quy này? n
Với n  2 ta có: 2an-1 – an-2 = 25 - 5 = 5 = an
Do đó, dãy a =5 cũng là lời giải của công thức đệ quy đã cho n
Cùng 1 công thức đệ quy có thể có nhiều lời giải.  Tại sao???
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy
Một công thức đệ quy không có các giá trị đầu (các điều kiện đầu).
 Có thể có (thường có) nhiều lời giải
Ví dụ: a = 2a n
n-1 – an-2 với n = 2, 3, 4,... Công thức đệ quy này có các lời giải: • a =5 na =3n na =n+1 n
Nếu cả công thức đệ quy và các điều kiện đầu đều được xác định, thì dãy số lời
giải của công thức đệ quy sẽ được xác định duy nhất. Ví dụ: a = 2a n
n-1 – an-2 với n = 2, 3, 4,..
với a0=0; a1 = 3
 Dãy số a =5 không phải là lời giải n
 Dãy số a =3n là lời giải duy nhất n
Công thức đệ quy là công thức cho phép tính giá trị của các đại
lượng theo từng bước, dựa vào các giá trị tính ở các bước trước và
một số giá trị đầu.
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy
Ta hiểu việc giải công thức đệ qui là việc tìm công thức dưới dạng hiện cho
số hạng tổng quát của dãy số thoả mãn công thức đệ qui đã cho.
Ví dụ: Cho công thức đệ quy: a = 2a n
n-1 – an-2 với n = 2, 3, 4,… a0=0; a1 = 3
Công thức dạng hiện của công thức đệ quy trên là dãy số a =3n n
a =3n được gọi là nghiệm (lời giải) của công thức đệ quy trên n
• Chưa có phương pháp giải mọi công thức đệ quy.
• Xét một số phương pháp giải:
– Phương trình đặc trưng giải Công thức đệ quy tuyến tính thuần nhất hệ số hằng
(sẽ viết tắt là CTĐQ TTTNHSH) – Phương pháp thế xuôi
– Phương pháp thế ngược – Cây đệ quy 125
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy: Phương pháp Phương trình đặc trưng
Định nghĩa. Công thức đệ qui tuyến tính thuần nhất hệ số hằng bậc k là công thức đệ qui sau a = c a n
1an−1 + … + ck nk
trong đó c là các hằng số, và c ≠ 0. i k Giải thích:
• Tuyến tính: vế phải là tổng của các số hạng trước số hạng an trong dãy số với các hệ số (c1,
c2, ..,ck) là hằng số (không phải là hàm phụ thuộc vào n)
• Thuần nhất: vế phải không có thêm số hạng nào khác với các số hạng a của dãy j
• Bậc k: vế phải có số hạng thứ (n-k) của dãy
Dãy số thoả mãn công thức đã cho là xác định duy nhất nếu đòi hỏi nó thoả mãn k điều kiện
đầu: a0 = C0, a1 = C1, ..., ak-1 = Ck-1,
trong đó C0, C1, ..., Ck-1 là các hằng số.
Ví dụ 1: a = 2a n
n-1 – an-2 với n = 2, 3, 4,... Công thức đệ quy này có một số lời giải như sau:
a =5 a =3n a =n+1 n n n
Ví dụ 2: a = 2a n
n-1 – an-2 với n = 2, 3, 4,… và các điều kiện đầu: a0=0; a1 = 3
 Dãy a =5 không là lời giải của công thức đệ quy đã cho n 126
 Dãy a =3n là lời giải của công thức đệ quy đã cho n
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Công thức đệ quy tuyến tính thuần nhất hệ số hằng
Ví dụ1: Đâu là CTĐQ TTTNHSH 1) a = 4a n n-1 +2nan-3 2) h = 2h n n-1 + 1 3) b = 5b n n-2 + 2(bn-3)2 4) q = 3 q n n-6 + qn-8 127
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 CTĐQ TTTNHSH bậc k Ví dụ 2:
• Công thức đệ quy Pn = (1.05)Pn-1
Là công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 1.
• Công thức đệ quy f = f n n-1 + fn-2
Là công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 2.
• Công thức đệ quy a = a n n-5
Là công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 5.
NGUYỄN KHÁNH PHƯƠNG 128
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH
• Ta sẽ tìm nghiệm dưới dạng a = rn, trong đó r là hằng số. n
• Dãy số {a = rn } thoả mãn CTĐQ đã cho n a = c a n
1an−1 + … + ck nk
nếu r thoả mãn phương trình: rn = c (chuyển vế
1rn−1 + … + c rnk, hay k rk c và × với
1rk−1 − … − c = 0 rkn) k
phương trình đặc trưng, còn nghiệm của nó sẽ được gọi là nghiệm đặc
trưng
của CTĐQ TTTNHSH.
• Ta có thể sử dụng nghiệm đặc trưng để thu được công thức cho dãy số.
NGUYỄN KHÁNH PHƯƠNG 129
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH
Xét công thức đệ quy tuyến tính thuần nhất hệ số hằng bậc 2: a = c a n
1an−1 + c2 n−2
Định lý 1. Cho c1, c2 là các hằng số thực.
Giả sử phương trình r2 - c1 r - c2 = 0 có 2 nghiệm phân biệt r1 và r2. Khi
đó dãy số {a } là nghiệm của công thức đệ quy n a = c a + c a n 1 n-1 2 n-2 khi và chỉ khi
a =  (r )n +  (r )n (1) n 1 1 2 2
n = 0, 1, ..., trong đó ,  1 2 là các hằng số.
NGUYỄN KHÁNH PHƯƠNG 130
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH
Chứng minh. Trước hết ta chứng minh rằng nếu r1 và r2 là hai
nghiệm phân biệt của phương trình đặc trưng, và  ,  là các hằng 1 2
số, thì dãy số {a } xác định bởi công thức (1) là nghiệm của công n thức đệ quy đã cho
• Thực vậy, do r r là nghiệm đặc trưng nên 1 2 r 2 = c r + c , 1 1 1 2 r 2 = c r + c 2 1 2 2
NGUYỄN KHÁNH PHƯƠNG 131
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH • Từ đó suy ra c a + c a 1 n-1 2 n-2
= c ( r n-1 + r n-1) + c ( r n-2 + r n-2) 1 1 1 2 2 2 1 1 2 2
=  r n-2(c r + c ) + r n-2(c r + c ) 1 1 1 1 2 2 2 1 2 2
=  r n-2 r 2 + r n-2 r 2 1 1 1 2 2 2
=  r n + r n 1 1 2 2 = a . n
NGUYỄN KHÁNH PHƯƠNG 132
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH
• Bây giờ ta sẽ chỉ ra rằng nghiệm {a } của công thức đệ quy n a = c a + c a
luôn có dạng (1) với  ,  nào đó. n 1 n-1 2 n-2 1 2
• Thực vậy, giả sử {a } là nghiệm của công thức đệ quy đã cho với điều n kiện đầu a = C , a = C , (2) 0 0 1 1
• Ta chỉ ra rằng có thể tìm được các số  ,  để cho (1) là nghiệm của 1 2
hệ thức với điều kiện đầu này
NGUYỄN KHÁNH PHƯƠNG 133
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH • Ta có
a = C = + , 0 0 1 2
a = C = r + r . 1 1 1 1 2 2
• Hệ phương trình tuyến tính phụ thuộc hai ẩn  ,  này có định thức là r - r 1 2 2 1
 0 (do r r ) có nghiệm duy nhất 1 2
= (C - C r )/(r - r ), = (C r - C )/(r - r ). 1 1 0 2 1 2 2 0 1 1 1 2
• Với những giá trị của  ,  vừa tìm được, dãy {a } xác định theo (1) là 1 2 n
nghiệm của hệ thức đã cho với điều kiện đầu (2). Do hệ thức đã cho cùng với
điều kiện đầu (2) xác định duy nhất một dãy số, nên nghiệm của hệ thức
được cho bởi công thức (1).
Định lý được chứng minh
NGUYỄN KHÁNH PHƯƠNG 134
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH
Ví dụ 1: Tìm lời giải cho công thức đệ quy a = a n
n-1 + 2an-2 với a0 = 2 và a1 = 7 ?
Giải: Phương trình đặc trưng của công thức đệ quy là
r2 – r – 2 = 0.
Có 2 nghiệm phân biệt r1 = 2 và r2 = -1.
Do đó, dãy {a } là lời giải của công thức đệ quy khi và chỉ khi: n
an = 12n + 2(-1)n với giá trị nào đó của 1 và 2.
Cho biểu thức an = 12n + 2(-1)n và các điều kiện đầu a0 = 2 và a1 = 7, ta có a0 = 2 = 1 + 2
a1 = 7 = 12 + 2 (-1)
Giả hệ phương trình này ta có: 1 = 3 và 2 = -1.
Do đó, lời giải của công thức đệ quy với ddieuf kiện đầu đã cho là dãy {a } với n a = 32n – (-1)n n
NGUYỄN KHÁNH PHƯƠNG 135
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Giải CTĐQ TTTNHSH
Ví dụ 2: Tìm lời giải cho công thức đệ quy (dãy Fibonacci) F = F + F , n  2, n n-1 n-2 F = 0, F = 1 0 1
Giả: Phương trình đặc trưng của công thức đệ quy
r2 – r – 1 = 0.
Có 2 nghiệm phân biệt là Leonardo Fibonacci 1170-1250 136
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Trường hợp nghiệm kép
Định lý 2: Cho c1, c2 là các hằng số thực, c2  0. Giả sử phương
trình r2 - c1 r - c2 = 0 có nghiệm kép r0. Khi đó dãy số {a } là n
nghiệm của công thức đệ qui a = c n
1 an-1 + c2 an-2 khi và chỉ khi arn nrn   n 1 0 2 0
n = 0, 1, ..., trong đó 1 , 2 là các hằng số.
NGUYỄN KHÁNH PHƯƠNG 137
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 3
Tìm nghiệm cho công thức đệ quy a = 6 a n
n-1 - 9 an-2
với điều kiện đầu a0 = 1 và a1 = 6. Giải:
Phương trình đặc trưng:
r2 - 6 r + 9 = 0 có nghiệm kép r = 3. Do đó nghiệm của hệ thức có dạng: a = n
1 3n + 2 n 3n.
Để tìm 1, 2 , sử dụng điều kiện đầu ta có
a0 = 1 = 1 ,
a
1 = 6 = 1 . 3 + 2 .1. 3
Giải hệ này ta tìm được 1 = 1 và 2 = 1.
Từ đó nghiệm của hệ thức đã cho là:
a = 3n + n 3n . n CTĐQ: a = c a n
1an−1 + … + ck nk
Phương trình đặc trưng: rk c1rk−1 − … − c = 0 k 138
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Trường hợp tổng quát
Định lý 3. Cho c1, c2, ..., c là các số thực, c k
k 0. Giả sử phương trình đặc trưng:
rk - c1 rk-1 - c2 rk-2 - . . . - c = 0 k
k nghiệm phân biệt r1, r2, ..., r . Khi đó dãy số {a } là nghiệm của k n công thức: a = c a , n
1 an-1 + c2 an-2 +...+ ck n-k khi và chỉ khi a = n +
n + . . . + r n n 1 r1 2 r2 k k
với n = 0, 1, 2,..., trong đó 1, 2, ..., là các hằng số k
NGUYỄN KHÁNH PHƯƠNG 139
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 4
Tìm nghiệm của công thức đệ quy a = 6 a n
n-1 - 11 an-2 + 6 an-3 với điều kiện đầu
a0 = 2, a1 = 5, a2 = 15.
Giải: Phương trình đặc trưng
r3 - 6 r2 + 11 r - 6 = 0
có 3 nghiệm r1 = 1, r2 = 2, r3 = 3. Vì vậy, nghiệm có dạng a = n
1 1n + 2 2n + 3 3n. CTĐQ: a = c a n
1an−1 + … + ck nk
Phương trình đặc trưng: rk c1rk−1 − … − c = 0 k 140
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 4
Sử dụng các điều kiện đầu ta có hệ phương trình sau đây để xác
định các hằng số  ,  ,  : 1 2 3
a = 2 = + +  0 1 2 3
a = 5 =  +  .2 +  .3 1 1 2 3
a = 15 = + .4 +  .9. 2 1 2 3
Giải hệ phương trình trên ta thu được
 = 1,  = -1  = 2. 1 2 3
Vậy nghiệm của công thức đã cho là
a = 1 - 2n + 2. 3n n 141
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Trường hợp tổng quát
Định lý 4. Cho c1, c2, ..., c là các hằng số thực, với c k k 0. k Giả sử PTĐT: k
r   ki c ri 0
rk - c1 rk-1 - c2 rk-2 - . . . - c = 0 k i 1 
t nghiệm phân biệt r1, r2, ..., r với bội tương ứng là m (với m = k). t 1,…,mt 1+…+mt
Khi đó, dãy {an} là nghiệm của CTĐQ TTTN hệ số hằng k a = c a , n
1 an-1 + c2 an-2 +...+ ck n-k a c a ni ni khi và chỉ khi i1 a = ( n
, +  , n + … +  , 𝑛 ) 𝑟 + t m   1 i  ( a j n
, +  , n + … +  , 𝑛 ) 𝑟 + ... n r n
 i,j  i ( i1  j0 
t,0 +  , n + … +  , 𝑛 ) 𝑟
với n=0,1,2,… và  là các hằng số 1  i t i,j
0  j m -1 dựa vào các điều kiện đầu i 142
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 5 Giải công thức đệ qui: c = – 4c n
n-1 + 3cn-2 + 18cn-3 , n  3,
c0 = 1; c1 = 2; c2 = 13.
Giải: Phương trình đặc trưng
r3 + 4r2 – 3r – 18 = (r – 2)(r + 3)2 = 0
Vậy nghiệm tổng quát của công thức: 143
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy: Các phương pháp khác
• Trên thực tế, khi phân tích độ phức tạp của một thuật toán nào đó nhờ
sử dụng công thức đệ quy tuyến tính, thì công thức đệ quy ít khi có bậc lớn hơn 2.
• Do đó, ta cũng có thể sử dụng hai phương pháp sau đây để giải công thức đệ quy
– Thay thế quay lui: xuất phát từ công thức đã cho, ta thế lần lượt lùi về các số
hạng phía trước của công thức đệ quy
– Cây đệ quy: biểu diễn công thức đệ quy bởi một cây đệ quy. Xuất phát từ công
thức đệ quy đã cho, ta biểu diễn các số hạng đệ quy có kích thước dữ liệu đầu
vào lớn ở mức A nào đó trên cây bởi các dữ liệu đầu vào nhỏ hơn ở mức A+1
của vây, và tính các số hạng không đệ quy. Cuối cùng, tính tổng tất cả các số
hạng không đệ quy ở tất cả các mức của cây.
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
Ví dụ 1: Giải công thức đệ quy
T(n)= T(n-1) + 2n với T(1) = 5 Giải:
Ta tiến hành thay thế lần lượt các số hạng của công thức đệ quy bằng cách lùi
lại các số hạng phía trước:
T(n) = T(n-1) + 2n
= T((n-1) -1) + 2(n-1) + 2n
= T(n-2) + 2 (n-1) + 2n
= T((n-2)-1) + 2(n-2) + 2(n-1) + 2n = T(n-3) +2(n-2)
+ 2(n-1) + 2n
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
• Tiếp tục thay thế lùi ta được
T(n) = T(n-3) + 2(n-2) + 2(n-1) + 2n
= T(n-4) + 2(n-3) + 2(n-2) + 2(n-1) + 2n ………… = T(n-i) + ∑ 2 𝑛 𝑗
giá trị hàm tại bước thay thế thứ i
• Giải công thức tổng ∑ 2 𝑛 𝑗 ta được
T(n) = T(n-i) + 2n(i-1) – 2(i-1)(i-1+1)/2 + 2n
= T(n-i) + 2n(i-1) – i2 + i + 2n (1)
• Giờ ta muốn loại bỏ số hạng T(n-i). Để làm được điều này, tại bước lặp thay thế thứ bao
nhiêu ta thu được điều kiện đầu T(1)?
Nhận thấy thu được T(1) khi n - i =1, tức là i = n - 1
• Thay thế vào biểu thức (1) ta có
T(n) = T(1) + 2n(n-1-1) – (n-1)2 + (n-1) + 2n
= 5 + 2n(n-2) – (n2-2n+1) + (n-1) + 2n = n2 + n + 3
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
Ví dụ 2: Giải công thức đệ quy
T(n)= T(n/2) + c
với T(1) = 2, và c là hằng số
T(n) = T(n/2) + c thay thế T(n/2)
= T(n/4) + c + c thay thế T(n/4)
= T(n/8) + c + c + c = T(n/23) + 3c = …
= T(n/2k) + kc
T(n) = T(n/2logn) + clogn “chọn k = logn”
= T(n/n) + clogn
=
T(1) + clogn = 2 +clogn
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 3 Hàm tính giai thừa
Xét thuật toán đệ quy tính n!
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 3 Factorial(n);
Bao nhiêu lần hàm Factorial được gọi khi chúng ta thực hiện lệnh Factorial(n); ?
• Khi n = 1, hàm Factorial được gọi 1 lần T(1) = 1 • Khi n > 1:
– Gọi hàm Factorial 1 lần, T(n) = 1 + T(n‐1)
– Cộng với số lần gọi trong lệnh đệ quy Factorial(n − 1)  T(n-1)
Do đó ta có công thức đệ quy: T(1) = 1
Tìm công thức dạng hiện tính T(n) với
T(n) = 1 + T(n − 1), n >1
mọi giá trị của n
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui Factorial(n);
T(n) = T(n − 1) + 1, n >1
= [T(n-2) +1] + 1 [có 2 số “1”]
=[[T(n-3)+1]+1]+1 [có 3 số “1”] =….
= T(n – (n-1)) + (n-1) [có n-1 số “1”] = T(1) + (n-1) = 1 + (n-1) = n
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Ví dụ 4
Có bao nhiêu phép nhân M(n) được thực thi khi thực hiện hàm Factorial?
• Khi n = 1 không phép nhân nào được thực hiện  M(1) = 0 • Khi n > 1:
– Ta thực hiện 1 lần phép nhân.
– Cộng với số lần thực hiện phép nhân trong lệnh gọi đệ quy Factorial(n − 1)  M(n-1)
Do đó ta có công thức đệ quy: M(0) = 0; M(1) = 0
M(n) = 1 + M(n − 1), n >1
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
VÝ dô 5. (Bμi to¸n th¸p Hμ néi). Trß ch¬i th¸p Hμ néi ®ưîc trình bμy như sau: “3
cäc a, b, c. Trªn cäc a cã mét chång gåm n c¸i ®Üa ®ưêng kÝnh gi¶m dÇn tõ dưíi lªn
trªn. CÇn ph¶i chuyÓn chång ®Üa tõ cäc a sang cäc c tu©n thñ qui t¾c:
1.
Mỗi lần chỉ chuyển 1 đĩa 2.
Chỉ được xếp đĩa có đường kính nhỏ hơn lên trên đĩa có đường kính lớn hơn.
Trong qu¸ trình chuyÓn ®ưîc phÐp dïng cäc b lμm cäc trung gian.

Bμi to¸n ®Æt ra lμ: Tìm công thức đệ qui cho h là sè lÇn di chuyÓn ®Üa Ýt nhÊt cÇn thùc n
hiÖn ®Ó hoàn thành nhiÖm vô ®Æt ra trong trß ch¬i th¸p Hμ néi. Cọc a Cọc c Cọc b 152
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Tower of Hanoi: n=5 1.
Mỗi lần chỉ chuyển 1 đĩa 2.
Chỉ được xếp đĩa có đường kính nhỏ hơn lên trên đĩa có đường kính lớn hơn Cọc a Cọc c Cọc b 153
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Bài toán: chuyển n đĩa từ cọc a sang cọc c sử dụng cọc b làm trung gian
Cần tìm h là sè lÇn di chuyÓn ®Üa Ýt nhÊt cÇn thùc hiÖn n h = 2h + 1, n ≥ 2. n n-1
ViÖc di chuyÓn ®Üa gåm 3 bưíc:
(1) ChuyÓn n-1 ®Üa tõ cäc a ®Õn cäc b sö dông cäc c lμm trung gian.
Bài toán kích thước n-1  Số lần di chuyển = hn-1
(2) ChuyÓn 1 ®Üa (®Üa víi ®ưêng kÝnh lín nhÊt) tõ cäc a ®Õn cäc c.  Số lần di chuyển = 1
(3) ChuyÓn n-1 ®Üa tõ cäc b ®Õn cäc c (sö dông cäc a lμm trung gian).
Bài toán kích thước n-1  Số lần di chuyển = hn-1 Cọc a Cọc c Cọc b 154
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750 Tower of Hanoi: n=5
(1) ChuyÓn n-1 ®Üa tõ cäc a ®Õn cäc b sö dông cäc c lμm trung gian.
Bài toán kích thước n-1  Số lần di chuyển = hn-1
(2) ChuyÓn 1 ®Üa (®Üa víi ®ưêng kÝnh lín nhÊt) tõ cäc a ®Õn cäc c.  Số lần di chuyển = 1
(3) ChuyÓn n-1 ®Üa tõ cäc b ®Õn cäc c (sö dông cäc a lμm trung gian).
Bài toán kích thước n-1  Số lần di chuyển = hn-1 Cọc a Cọc c Cọc b 155
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 2: Thay thế quay lui
Ta có thể tìm được công thức trực tiếp cho h bằng phương pháp thế n quay lui: h = 2 h n n−1 + 1 = 2 (2 hn−2 + 1) + 1 = 22 hn−2 + 2 + 1
= 22(2 hn−3 + 1) + 2 + 1 = 23 hn−3 + 22 + 2 + 1 …
= 2n−1 h1 + 2n−2 + … + 2 + 1
= 2n−1 + 2n−2 + … + 2 + 1 (do h1 = 1) = 2n − 1 156
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 3: Cây đệ quy
• Để giải công thức đệ quy bằng phương pháp này: ta sẽ vẽ cây đệ quy mô tả công thức đã cho
• Mỗi nút của cây tương ứng với 1 hàm dữ liệu đầu vào. Càng đi xuống phía dưới cây,
kích thước dữ liệu đầu vào càng giảm.
• Mức cuối cùng của cây tương ứng với kích thước dữ liệu đầu vào nhỏ nhất
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 1: Thuật toán đệ quy giải bài toán dãy con lớn nhất O(n) O(n)
T(n) = 2T(n/2)+O(n)
Giải bằng phương pháp cây đệ T(n/2) quy, ta sẽ thu được: T(n/2)
 T(n) = O(nlogn) 158
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 1: Giải công thức đệ quy:
T(n) = 2T(n/2) + n, T(1) = 4 n*4
• Giá trị hàm T(n) bằng tổng các giá trị tại tất cả các mức:
• Vì mức cuối (sâu nhất) log2n có giá trị = 4n, ta có
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
1.6. Giải công thức đệ quy:
Phương pháp 3: Cây đệ quy
• Ví dụ 2: Giải công thức đệ quy
T(n) = T(n/) + f(n), T() = c
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 2: Giải công thức đệ quy
T(n) = T(n/) + f(n), T() = c Iteration Cost 0 TT(n) f(n) 1 f(n/) T(n/) T(n/)    T(n/) 2 T(n/ 2 2)    T(n/2)
T(n/2)    T(n/2) f(n/2) . . . . i i f(n/i) . . log n
• Giá trị của hàm bằng tổng các giá trị trên tất cả các mức của cây:
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Đầu vào: Mảng S gồm n phần tử: S[0],…,S[n-1] đã sắp xếp theo thứ tự
tăng dần; Giá trị key.
Đầu ra: chỉ số của phần tử có giá trị key nếu có; -1 nếu key không xuất hiện trong mảng S
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1;
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN } 162
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo hi 163
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo mid hi 164
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo hi 165
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo mid hi 166
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo hi 167
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo mid hi 168
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo hi 169
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo hi mid 170
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; key=33 else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); key=31?? } else return -1; } 6
13 14 25 33 43 51 53 64 72 84 93 95 96 97 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 lo hi mid 171
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
Đầu vào: Mảng S gồm n phần tử: S[0],…,S[n-1] đã sắp xếp theo thứ tự
tăng dần; Giá trị key.
Đầu ra: chỉ số của phần tử có giá trị key nếu có; -1 nếu key không xuất hiện trong mảng S
int binsearch(int low, int high, int S[], int key) { if (low <= high) { mid = (low + high) / 2; if (S[mid]==key) return mid; else if (key < S[mid])
return binsearch(low, mid-1, S, key); else
return binsearch(mid+1, high, S, key); } else return -1; }
 binsearch(0, n-1, S, key);
Có bao nhiêu lần hàm binsearch được gọi trong trường hợp tồi nhất ? 172
Downloaded by v?n ti?n Lê (vantienle525@gmail.com) lOMoARcPSD|36442750
Ví dụ 3: Tìm kiếm nhị phân dưới dạng đệ quy
int binsearch(int low, int high, int S[], int key) { if (low <= high)  T(0) = ? {
 binsearch(0, -1, S, key); mid = (low + high) / 2; if (S[mid]==key) return mid;  T(1) = ? else if (key < S[mid])
return binsearch(low, mid-1, S, key);
 binsearch(0, 0, S, key); else
 binsearch(0, -1, S, key);
return binsearch(mid+1, high, S, key); }
 binsearch(1, 0, S, key); else return -1; }
 binsearch(0, n-1, S, key);
Gọi T(n): số lần hàm binsearch được gọi trong trường hợp tồi nhất khi mảng S n phần tử • T(0) = 1 Công thức đệ quy:T(1) = 2
T(n) = T(n/2) + 1
T(2) = T(1) + 1 = 3 T(0) = 1
T(4) = T(2) + 1 = 4 T(1) = 2
T(8) = T(4) + 1 = 4 + 1 = 5
Bài tập: Hãy giải công thức đệ quy này 173
T(n) = T(n/2) + 1
Downloaded by v?n ti?n Lê (vantienle525@gmail.com)