SlideShare a Scribd company logo
1 of 115
Download to read offline
CẤU TRÚC DỮ LIỆU
VÀ GIẢI THUẬT
DATA STRUCTURES AND ALGORITHMS
ThS. Lê Quang Hòa – Bộ môn Toán - Tin Viện Toán ứng dụng và tin học
NỘI DUNG
▪ Mục đích, yêu cầu
▪ Nội dung môn học
▪ Tài liệu tham khảo
2
Mục đích
▪ Giới thiệu các kiến thức cơ bản về cấu trúc dữ liệu
và các thuật toán
▪ Học cách sử dụng các cấu trúc dữ liệu như là một
công cụ hỗ trợ việc phát triển các thuật toán
▪ Trình bày các thuật toán sắp xếp (sorting), tìm
kiếm (searching), các thuật toán trên đồ thị
(graphs)
3
Mục tiêu
▪ Biết lựa chọn phương pháp lưu trữ dữ liệu thích
hợp để cài đặt thuật toán giải các bài toán trong
thực tế ứng dụng
▪ Biết cách tiếp cận để phát triển thuật toán giải các
bài toán thực tế
4
Nội dung
▪ Các khái niệm cơ bản
▪ Các sơ đồ thuật toán
▪ Các cấu trúc dữ liệu cơ bản
▪ Cây
▪ Đồ thị
▪ Sắp xếp
▪ Tìm kiếm
5
Tài liệu tham khảo
▪ Robert Sedgewick. Algorithms in C++, Parts 1-4: Fundamentals, Data
Structures, Sorting, Searching. 3th Edition, Addison-Wesley, 1999.
▪ 2. Robert Sedgewick. Algorithms in C++ Part 5: Graph Algorithms (3rd Edition).
3th Edition, Addison-Wesley, 2002.
▪ 3. Michael T. Goodrich, Roberto Tamassia, David M. Mount, Data Structures and
Algorithms in C++. 704 pages. Wiley, 2003.
▪ 4. T.H. Cormen, C.E. Leiserson, R.L. Rivest. Introduction to Algorithms .Third
Edition, MIT Press, 2009. (Có bản dịch tiếng Việt)
▪ 5. Nguyễn Đức Nghĩa. . Cấu trúc dữ liệu và thuật toán. NXB Đại học Bách khoa
Hà nội, 2013. 368 trang.
▪ 6. Đỗ Xuân Lôi. Cấu trúc dữ liệu và giải thuật. NXB ĐH Quốc gia, Hà nội, 2005
6
1. Các khái niệm cơ bản
1.1 Ví dụ
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
7
1. Các khái niêm cơ bản
1.1 Ví dụ
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
8
1.1 Ví dụ: tìm dãy con tổng lớn nhất
( The maximum subarray problem)
Cho dãy số gồm n số: , , … , , dãy gồm liên
tiếp các số , , … , với 1 ≤ ≤ ≤ là
dãy con của dãy đã cho, tìm tổng lớn nhất của các
dãy con, dãy con có tổng lớn nhất gọi là dãy con
lớn nhất
Ví dụ cho dãy -1, 11, -4, 13, -5, 2 thì dãy con lớn
nhất là 11, -4, 13 với tổng lớn nhất các dãy con là
11+(-4) + 13=20
9
Một số cách giải
▪ Duyệt toàn bộ(brute force)
▪ Duyệt toàn bộ cải tiến
▪ Thuật toán đệ quy (Recursive algorithm)
▪ Thuật toán quy hoạch động (Dynamic
programming)
10
Duyệt toàn bộ (brute force)
▪ Thuật toán đơn giản là: tìm tất cả các dãy con có
thể : , , … , với 1 ≤ ≤ ≤ và tính
tổng của mỗi dãy con để tìm ra tổng lớn nhất.
▪ tổng số các dãy con có thể của dãy đã cho là:
, 1 + , 2 = +
11
Duyệt toàn bộ (brute force)
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
Duyệt toàn bộ (brute force)
▪ Phân tích tuật toán: số phép cộng phải thực hiện là
số lần thực hiện lệnh sum+=a[k]
▪ Số phép cộng là:
▪ ∑ ∑ − + 1 = ∑ (1 + 2+. . +( − ) =
∑ (
( )( )
)= ∑ ( +
1) = + = + +
13
Duyệt toàn bộ (brute force)
14
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)
Duyệt toàn bộ cải tiến
▪ Nhận xét tổng các phần tử từ vị trí i đến j sẽ bằng
tổng các phần tử từ i đến j-1 cộng với a[j]
▪ Ta cải tiến thuật toán như sau:
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; }
} 15
Duyệt toàn bộ cải tiến
▪ Phân tích tuật toán: số phép cộng phải thực hiện là
số lần thực hiện lệnh sum+=a[j]
▪ Số phép cộng là:
▪ ∑ ( − ) = + − 1 + ⋯ + 1 = +
▪ Số phép cộng đúng bằng số lượng dãy con, vậy
còn thuật toán nào tốt hơn không?
16
Thuật toán đệ quy
▪ Thuật toán đệ quy dùng kỹ thuật chia để trị (divide
and conquer) gồm các bước:
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
oTrườ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
17
Thuật toán đệ quy
▪ Để 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
18
Thuật toán đệ quy
▪ Để 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
19
Thuật toán đệ quy
▪ Do đó, nếu kí hiệu tổ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
Thuật toán đệ quy
maxSub(a, low,high);
{ if(low=high) return a[low]
Else
{ mid=(low+high)/2;
wL=maxSub(a, low,mid);
wR=maxSub(a, mid,high);
wM=maxCrossMidPoint(a,low,mid,high);
return max(wL,wR,wM);}
}
21
Thuật toán đệ quy
Việc tìm tổ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 tổ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 tổ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 tổng wMR của dãy con lớn nhất bắt đầu ở vị trí
mid+1
– Khi đó wM = wML + wMR.
22
Thuật toán đệ quy
Ở dãy nửa trái: tìm tổ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 tổng wMR của dãy con lớn nhất bắt
đầu ở vị trí mid+1
Khi đó wM = wML + wMR
23
Ví dụ tính tổng wM của dãy con lớn nhất bắt đầu ở
nửa dãy trái và kết thúc ở nửa dãy phải
24
Thuật toán đệ quy
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
2
+
2
+ = 2
2
+
= 1
> 1
Giải ra ta được T(n)=nlogn
25
Thuật toán đệ quy
Ta khẳng định rằng T(2k) = k.2k. Ta chứng minh bằng qui
nạp
• Cơ sở qui nạp: Nếu k=0 thì T(20) = T(1) = 0 = 0.20.
• Chuyển qui nạp: Nếu k>0, giả sử rằng T(2k-1) = (k-1)2k-1 là
đúng. Khi đó
T(2k) = 2T(2k-1)+2k = 2(k-1).2k-1 + 2k = k.2k.
• Quay lại với ký hiệu n, ta có T(n) = n log n
26
Thuật toán đệ quy
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
Ta sẽ phải gọi lệnh: MaxSub(a, 1, 10)
27
1 2 3 4 5 6 7 8 9 10
13 -3 -25 20 -3 -16 -23 18 20 -7
So sánh số phép tính 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 28
So sánh số phép tính các thuật toán
29
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?
Thuật toán Quy hoạch động (Dynamic
programming)
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)
30
Thuật toán Quy hoạch động (Dynamic
programming)
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)
31
Ví dụ
1. Phân rã:
• Gọi si là tổng của dãy con lớn nhất của dãy a1, a2, ..., ai , i
= 1, 2, ..., n.
• Rõ ràng, sn là 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:
• s1 = a1
• Giả sử i > 1 và ta đã biết giá trị sk với k = 1, 2, ..., i-1. Ta
cần tính giá trị si là tổng của dãy con lớn nhất của dãy: a1,
a2, ..., ai-1 , ai
32
Ví dụ
Nhận thấy rằng: dãy con lớn nhất của dãy a1, a2, ..., ai-1, ai có thể
hoặc bao gồm phần tử ai hoặc không bao gồm phần tử ai, do đó, dãy
con lớn nhất của dãy a1, a2, ..., ai-1, ai chỉ có thể là một trọng 2 dãy
sau:
– 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, ..., ai , và dãy con này kết thúc tại
phần tử ai.
Do đó, ta có si = max {si-1, ei}, i = 2, …, n.
với ei là tổng của dãy con lớn nhất a1, a2, ..., ai và dãy con này kết
thúc tại ai.
Để tính ei, ta xây dựng công thức đệ quy:
– e1 = a1;
– ei = max {ai, ei-1 + ai}, i = 2, ..., n.
33
Ví dụ
MaxSub(a)
{
smax=a[1];
ei=a[1];
imax=1;
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;}}
}
34
Ví dụ
Smax=13, ei=13, imax=1
i=2 ei=10
i=3 ei=-15
i=4 ei=20 smax=20 imax=4
i=5 ei=17
i=6 ei=1
i=7 ei=-22
i=8 ei=18
i=9 ei=38 smax=38 imax=9
i=10 ei=31 35
1 2 3 4 5 6 7 8 9 10
13 -3 -25 20 -3 -16 -23 18 20 -7
So sánh bốn 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)
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
36
1. Các khái niêm cơ bản
1.1 Ví dụ
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
37
Thuật toán (Algorithm)
Trong 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
38
Thuật toán (Algorithm)
39
Ví dụ
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: 13
• Yêu cầu: thiết kế thuật toán giải bài toán trên
40
Tìm số lớn nhất dãy sau
41
Các bước thực hiện
42
Chỉnh sửa
43
Tổng quát
44
Thuật toán (Algorithm)
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.
45
Thuật toán (Algorithm)
– 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
46
Cấu trúc dữ liệu
Cấu trúc dữ liệu là cách lưu trữ, tổ chức dữ liệu có thứ tự,
có hệ thống để dữ liệu có thể được sử dụng một cách hiệu
quả
• Interface: Mỗi cấu trúc dữ liệu có một Interface. Interface
biểu diễn một tập hợp các phép tính mà một cấu trúc dữ
liệu hỗ trợ. Một Interface chỉ cung cấp danh sách các phép
tính được hỗ trợ, các loại tham số mà chúng có thể chấp
nhận và kiểu trả về của các phép tính này.
• Implementation (có thể hiểu là sự triển khai): Cung cấp sự
biểu diễn nội bộ của một cấu trúc dữ liệu. Implementation
cũng cung cấp phần định nghĩa của giải thuật được sử
dụng trong các phép tính của cấu trúc dữ liệu
47
Đặc điểm cấu trúc dữ liệu
• Chính xác: Sự triển khai của Cấu trúc dữ liệu nên triển
khai Interface của nó một cách chính xác.
• Độ phức tạp về thời gian (Time Complexity): Thời gian
chạy hoặc thời gian thực thi của các phép tính của cấu trúc
dữ liệu phải là nhỏ nhất có thể.
• Độ phức tạp về bộ nhớ (Space Complexity): Sự sử dụng
bộ nhớ của mỗi phép tính của cấu trúc dữ liệu nên là nhỏ
nhất có thể
48
Cần thiết có cấu trúc dữ liệu
• Tìm kiếm dữ liệu: Giả sử có 1 triệu hàng hóa được lưu
giữ vào trong kho hàng hóa. Và giả sử có một ứng dụng
cần để tìm kiếm một hàng hóa. Thì mỗi khi thực hiện tìm
kiếm, ứng dụng này sẽ phải tìm kiếm 1 hàng hóa trong 1
triệu hàng hóa. Khi dữ liệu tăng lên thì việc tìm kiếm sẽ
càng trở lên chậm và tốn kém hơn.
• Tốc độ bộ vi xử lý: Mặc dù bộ vi xử lý có tốc độ rất cao,
tuy nhiên nó cũng có giới hạn và khi lượng dữ liệu lên tới
hàng tỉ bản ghi thì tốc độ xử lý cũng sẽ không còn được
nhanh nữa.
• Đa yêu cầu
49
Giải bài toán là gì
Problem solving
– Là quá trình đặt bài toán và phát triển chương
trình máy tính để giải bài toán đặt ra
• Lời giải bài toán bao gồm:
– Thuật toán (Algorithms)
• Algorithm: là dãy các bước cần thực hiện để từ dữ
liệu vào (input) đưa ra kết quả đầu ra (output) của
bài toán trong thời gian hữu hạn.
– Cấu trúc dữ liệu (Data structures):
• Cách tổ chức lưu trữ dữ liệu vào - ra
50
Vòng đời của phần mềm (The Life Cycle of
Software)
Vòng đời của phần mềm
– Là một quá trình dài và liên tục
– Đòi hỏi để phát triển một phần mềm có chất lượng tốt
– Lập trình viên có thể di chuyển từ một pha trong vòng đời
sang bất kỳ pha nào còn lại
51
Vòng đời của phần mềm (The Life Cycle of
Software)
9 pha:
• Phase 1: Chỉ rõ đặc điểm kỹ thuật (Specification) (đặc tả)
• Phase 2: Thiết kế (Design)
• Phase 3: Phân tích rủi ro (Risk Analysis)
• Phase 4: Kiểm thử (Verification)
• Phase 5: Lập trình (Coding)
• Phase 6: Test thử (Testing)
• Phase 7: Tinh chế lời giải (Refining the Solution)
• Phase 8: Sản xuất (Production)
• Phase 9: Bảo trì (Maintenance)
52
Vòng đời của phần mềm (The Life Cycle of
Software)
Phase 1: Đặc tả (Specification)
– Các khía cạnh của bài toán cần chỉ rõ:
• Dữ liệu đầu vào là gì (What is the input data?)
• Dữ liệu nào là đúng đắn, là không đúng đắn?
• Ai là người sử dụng phần mềm và giao diện người dùng cần
được thiết kế như thế nào?
• Cần phát hiện những lỗi gì và cần thông báo như thế nào về
chúng?
• Có thể có các giả thiết nào?
• Có những trường hợp đặc biệt nào?
• Dạng của dữ liệu đưa ra như thế nào?
• Cần có các tài liệu gì?
• Cái gì cần phát triển trong tương lai?
– Chương trình mẫu (Chương trình mô phỏng dáng điệu của một
phần của sản phẩm phần mềm cần phát triển)
53
Vòng đời của phần mềm (The Life Cycle of
Software)
Phase 2: Thiết kế (Design). Quá trình thiết kế bao gồm:
– Chia chương trình ra thành các modules (Modules:
là các đơn vị chương trình độc lập)
– Chỉ rõ mục đích của mỗi module
– Chỉ rõ dòng dữ liệu trong các modules
– Xác định giao diện (Interfaces - Cơ cấu giao tiếp giữa các
mô đun)
54
Vòng đời của phần mềm (The Life Cycle of
Software)
Phase 3: Phân tích rủi ro (Risk Analysis)
Phase 4: Kiểm thử (Verification)
– Chứng minh tính đúng đắn của thuật toán bằng các
phương pháp hình thức, …
Phase 5: Cài đặt (Coding)
– Liên quan đến việc chuyển thiết kế sang một ngôn ngữ
lập trình cụ thể
– Loại trừ các lỗi ngữ pháp
55
Vòng đời của phần mềm (The Life Cycle of
Software)
Phase 6: Test thử (Testing)
– Liên quan đến việc loại bỏ các lỗi logic
– Dữ liệu test phải bao gồm:
• Dữ liệu đúng đắn với kết quả biết trước
• Dữ liệu không đúng đắn
• Dữ liệu ngẫu nhiên
• Dữ liệu thực tế
56
Vòng đời của phần mềm (The Life Cycle of
Software)
Phase 7: Tinh chế lời giải (Refining the Solution)
– Do chương trình được phát triển với những giả thiết nhất
định nên cần tìm cách giảm nhẹ các giả thiết được bổ sung
đối với đầu vào, đầu ra
– Bổ sung thêm các chức năng
– Tăng các biện pháp kiểm tra lỗi
57
Vòng đời của phần mềm (The Life Cycle of
Software)
• Phase 8: Xuất xưởng (Production)
– Bàn giao sản phẩm cho người dùng.
– Người dùng sử dụng phần mềm
• Phase 9: Bảo trì (Maintenance)
– Sửa chữa các lỗi do người sử dụng phát hiện.
– Bổ sung thêm chức năng.
– Cải tiến một số bộ phận để đáp ứng yêu cầu của người
dùng tốt hơn
58
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
59
Ví dụ: Xây dựng thuật toán giải bài toán
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
60
Đặt vấ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Ớ
61
Độ phức tạp của thuật toán
Đánh giá độ phức tạp tính toán của thuật toán là đánh giá
lượng tài nguyên các loại mà thuật toán đòi hỏi sử dụng.
Có hai loại tài nguyên quan trọng đó là thời gian và 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.
• Thời gian tính phụ thuộc vào dữ liệu vào.
• Đị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ó.
• 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 vào.
62
Độ phức tạp của thuật toán
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).
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
63
Độ phức tạp của thuật toán
• 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)
Vậy ta có 3 loại thời gian tính
64
Độ phức tạp của thuật toán
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
65
Độ phức tạp của thuật toán
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.
• Dễ xác định
Có hai cách để đánh giá thời gian tính:
• Từ thời gian chạy thực nghiệm
• Lý thuyết: khái niệm xấp xỉ tiệm cận 66
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
• Đo thời gian chạy trung bình
• Vẽ đồ thị kết quả
67
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ắt 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 dẫn
đến rất khó khăn và tốn nhiều chi phí. 68
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
• Để 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
69
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)
70
Phép toán cơ bản
• Đo thời gian tính bằng đơn vị đo nào?
• Định nghĩa. Ta gọi phép toán cơ bản là phép toán có thể
thực hiện với thời gian bị chặn bởi một hằng số không phụ
thuộc vào kích thước dữ liệu.
• Để tính toán thời gian thực hiện của thuật toán ta sẽ đếm
số phép toán cơ bản mà nó phải thực hiện.
71
1. Các khái niêm cơ bản
1.1 Ví dụ
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
72
Kí hiệu tiệm cận (Asymptotic notation)
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 73
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ă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 các hằng số
dương c1,c2 sao cho nó bị kẹp giữa c1g(n) và c2g(n) với
giá trị n đủ lớn
Ta nói g(n) đánh giá tiệm cận đúng cho f(n) và viết f(n)=
Θ(g(n))
74
Kí hiệu Theta
75
Kí hiệu Theta
Ví dụ 1: chứng minh rằng 10n2-3n= Θ(n2)
Ta cần chỉ ra với các giá trị nào của n0,c1,c2 thì bất đẳng
thức trong định nghĩa của ký hiệu theta là đúng
c1 n2 ≤ f(n) = 10n2-3n ≤ c2 n2 với mọi n≥ n0
Gợi ý: lấy c1 nhỏ hơn số hạng với số mũ cao nhất, c2
lớn hơn
Chọn c1=1, c2=11, n0=1
76
Kí hiệu Theta
Ví dụ 2: chứng minh rằng n2-3n= Θ(n2)
Ta cần chỉ ra với các giá trị nào của n0,c1,c2 thì bất đẳng
thức trong định nghĩa của ký hiệu theta là đúng
c1 n2 ≤ f(n) = n2-3n ≤ c2 n2 với mọi n≥ n0
Gợi ý: lấy c1 nhỏ hơn số hạng với số mũ cao nhất, c2
lớn hơn
Chọn c1=1/4, c2=1, n0=7
77
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
Θ(g(n)) ={f(n): tồn tại các hằng số dương c và n0 sao cho 0≤
f(n) ≤ cg(n), với mọi n≥ n0} (tập tất cả các hàm có độ tăng nhỏ
hơn hoặc bằng tốc độ tăng của g(n)
Hàm f(n) thuộc vào tập O(g(n)) nếu tồn tại các hằng số dương c
sao cho f(n) ≤ cg(n) với giá trị n đủ lớ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))
78
Kí hiệu O lớn (big Oh)
79
Kí hiệu O lớn (big Oh)
Ví dụ 1: Chứng minh rằng 2n + 10 = O(n)
Ví dụ 2: Chứng minh rằng 7n - 2 = O(n)
Ví dụ 3: Chứng minh rằng 3n3 + 20n2 + 5 = O(n3)
Ví dụ 4: Chứng minh rằng 3 log2n + 5 = O(log2n)
80
Một số quy tắc O lớn
Nếu f(n) là đa thức bậc d thì f(n)=O(nd) tức là
o Bỏ qua các số hạng có số mũ thấp hơn d
o Bỏ qua các hằng số
Nên tìm hàm g(n) có tốc độ tăng càng chậm càng tốt
o Sử dụng các lớp hàm có tốc độ tăng nhỏ nhất có thể
o Sử dụng hàm đơn giản nhất có thể
81
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 và n0 sao cho 0≤
cg(n) ≤ f(n), với mọi n≥ n0} (tập tất cả các hàm có độ tăng lớn
hơn hoặc bằng tốc độ tăng của g(n)
Hàm f(n) thuộc vào tập Ω(g(n)) nếu tồn tại các hằng số dương c
sao cho cg(n) ≤ f(n) với giá trị n đủ lớn
Ta nói g(n) là cận dưới tiệm cận của f(n) và viết f(n)= Ω(g(n))
82
Ký hiệu Omega Ω
83
Các ký hiệu tiệm cận
84
Các ký hiệu tiệm cận
Định lý: đối với hai hàm g(n) và f(n) bất kỳ, ta có f(n)= (g(n)) khi
và chỉ khi f(n)=O(g(n)) và f(n)=Ω (g(n))
85
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)) 86
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
87
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)
88
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
Ví dụ: Thuật toán sắp xếp chèn (Insertion sorting) có thời gian
trung bình cỡ n2
89
Một số lớp thuật toán cơ bản
▪ Hằng số ≈ (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)
▪ Đa thức (polynomial) ≈ O(nk), n>=1
▪ Hàm mũ (exponential) ≈ O(an), a>1
90
Một số lớp thuật toán cơ bản
Những hàm nào trong số những hàm sau giống nhau
hơn?
n1000 n2 2n
1000n2 3n2 2n3
91
Tốc độ tăng của một số hàm cơ bản
92
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
93
Phân loại thời gian tính của thuật toán
– 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 và k là các hằng số tương ứng
94
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 là 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ó cận trên là O(g(n)) và cận dưới là Ω(g(n))
95
Cách nhớ các kí hiệu
96
Chú ý
• Giả sử có 2 thuật toán:
• Thuật toán A có thời gian chạy
30000n
• Thuật toán B có thời gian chạy 3n2
• 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
97
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, ...
98
Bài toán dễ giải, khó giải và không giải
được
• 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
99
1. Các khái niêm cơ bản
1.1 Ví dụ
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
100
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
language), cho phép:
– Mô 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 kê một số câu lệnh chính được sử dụng
trong giáo trình để mô tả thuật toán 101
1.4. Giả ngôn ngữ (Pseudocode)
102
1.4. Giả ngôn ngữ (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;
103
1.4. Giả ngôn ngữ (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; 104
1.4. Giả ngôn ngữ (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;
105
1.4. Giả ngôn ngữ (Pseudocode)
▪ Vào/ra:
read(X); /* X là biến */
print(data);
hoặc print(thông báo);
• Hàm và thủ tục:
Function name(arguments)
begin
khai báo biến;
các câu lệnh trong hàm;
return (value);
end;
106
1.4. Giả ngôn ngữ (Pseudocode)
Procedure name(arguments)
begin
khai báo biến;
các câu lệnh trong thủ tục;
end;
107
1. Các khái niêm cơ bản
1.1 Ví dụ
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
108
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 dẫn
đến rất khó khăn và tốn nhiều chi phí. 109
Tính toán thời gian tính của thuật toán
• Để 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 vậy, ta cần đánh giá thuật toán theo hướng xấp xỉ
tiệm cận
110
Tính toán thời gian tính của thuật toá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à 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. 111
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
phép toán cơ bản là phép toán có thể thực hiện với thời
gian bị chặn bởi 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) 112
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, Q là hai đoạn chương trình thực thi một thuật
toán P thực hiện xong đến Q:
time(P,Q)=time(P)+time(Q)
2. Vòng lặp for: for i=1 to m do P(i)
Với thời gian thực hiện P(i) là t(i): time(for)=∑ ( )
3. 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)) 113
Phân tích độ phức tạp của thuật toán:
Các kĩ thuật cơ bản
4. 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.
114
Câu hỏi
115

More Related Content

Similar to Tuan1_GioiThieu.pdf

Chuyen de so hoc nang cao VN
Chuyen de so hoc nang cao VNChuyen de so hoc nang cao VN
Chuyen de so hoc nang cao VNvothimyhanh
 
ThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáNThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáNguest717ec2
 
ChuyenDeSoHocVMF.pdf
ChuyenDeSoHocVMF.pdfChuyenDeSoHocVMF.pdf
ChuyenDeSoHocVMF.pdfHngAnhV13
 
Diophantine equations Phương trình diophant
Diophantine equations Phương trình diophantDiophantine equations Phương trình diophant
Diophantine equations Phương trình diophantBui Loi
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5Nguyễn Công Hoàng
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 1
Giáo trình Phân tích và thiết kế giải thuật - CHAP 1Giáo trình Phân tích và thiết kế giải thuật - CHAP 1
Giáo trình Phân tích và thiết kế giải thuật - CHAP 1Nguyễn Công Hoàng
 
Bai toan va thuat toan
Bai toan va thuat toanBai toan va thuat toan
Bai toan va thuat toanHữu Duy Duy
 
Mot so bai toan quy hoach dong
Mot so bai toan quy hoach dongMot so bai toan quy hoach dong
Mot so bai toan quy hoach dongANHMATTROI
 
Quy hoạch động
Quy hoạch độngQuy hoạch động
Quy hoạch độnghana_dt
 
Một số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanh
Một số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanhMột số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanh
Một số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanhBồi Dưỡng HSG Toán Lớp 3
 
Ctdl lab07-cac thuat-toan_sap_xep
Ctdl lab07-cac thuat-toan_sap_xepCtdl lab07-cac thuat-toan_sap_xep
Ctdl lab07-cac thuat-toan_sap_xepNguyễn Ngọc Hà
 

Similar to Tuan1_GioiThieu.pdf (20)

Chuyen de so hoc nang cao VN
Chuyen de so hoc nang cao VNChuyen de so hoc nang cao VN
Chuyen de so hoc nang cao VN
 
ThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáNThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáN
 
ĐỒ ÁN - SẮP XẾP LỊCH THI ĐẤU TENNIS BẰNG THUẬT TOÁN CHIA ĐỂ TRỊ (Ngôn ngữ C).doc
ĐỒ ÁN - SẮP XẾP LỊCH THI ĐẤU TENNIS BẰNG THUẬT TOÁN CHIA ĐỂ TRỊ (Ngôn ngữ C).docĐỒ ÁN - SẮP XẾP LỊCH THI ĐẤU TENNIS BẰNG THUẬT TOÁN CHIA ĐỂ TRỊ (Ngôn ngữ C).doc
ĐỒ ÁN - SẮP XẾP LỊCH THI ĐẤU TENNIS BẰNG THUẬT TOÁN CHIA ĐỂ TRỊ (Ngôn ngữ C).doc
 
ChuyenDeSoHocVMF.pdf
ChuyenDeSoHocVMF.pdfChuyenDeSoHocVMF.pdf
ChuyenDeSoHocVMF.pdf
 
Diophantine equations Phương trình diophant
Diophantine equations Phương trình diophantDiophantine equations Phương trình diophant
Diophantine equations Phương trình diophant
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 1
Giáo trình Phân tích và thiết kế giải thuật - CHAP 1Giáo trình Phân tích và thiết kế giải thuật - CHAP 1
Giáo trình Phân tích và thiết kế giải thuật - CHAP 1
 
Phép Tính Tích Phân Và Áp Dụng.doc
Phép Tính Tích Phân Và Áp Dụng.docPhép Tính Tích Phân Và Áp Dụng.doc
Phép Tính Tích Phân Và Áp Dụng.doc
 
Pt to-hop-nhi-thuc-newton
Pt to-hop-nhi-thuc-newtonPt to-hop-nhi-thuc-newton
Pt to-hop-nhi-thuc-newton
 
Thuat Toan
Thuat ToanThuat Toan
Thuat Toan
 
Thuat Toan 2
Thuat Toan 2Thuat Toan 2
Thuat Toan 2
 
Bai toan va thuat toan
Bai toan va thuat toanBai toan va thuat toan
Bai toan va thuat toan
 
250 bài ôn luyện Toán 4 và 25 đề tham khảo
250 bài ôn luyện Toán 4 và 25 đề tham khảo250 bài ôn luyện Toán 4 và 25 đề tham khảo
250 bài ôn luyện Toán 4 và 25 đề tham khảo
 
Mot so bai toan quy hoach dong
Mot so bai toan quy hoach dongMot so bai toan quy hoach dong
Mot so bai toan quy hoach dong
 
Quy hoạch động
Quy hoạch độngQuy hoạch động
Quy hoạch động
 
Quy hoạch động
Quy hoạch độngQuy hoạch động
Quy hoạch động
 
Quy Hoach Dong
Quy Hoach DongQuy Hoach Dong
Quy Hoach Dong
 
GV
GVGV
GV
 
Một số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanh
Một số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanhMột số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanh
Một số biện pháp giúp học sinh Tiểu học giải các bài toán tính nhanh
 
Ctdl lab07-cac thuat-toan_sap_xep
Ctdl lab07-cac thuat-toan_sap_xepCtdl lab07-cac thuat-toan_sap_xep
Ctdl lab07-cac thuat-toan_sap_xep
 

Recently uploaded

Catalogue cáp điện GOLDCUP 2023(kỹ thuật).pdf
Catalogue cáp điện GOLDCUP 2023(kỹ thuật).pdfCatalogue cáp điện GOLDCUP 2023(kỹ thuật).pdf
Catalogue cáp điện GOLDCUP 2023(kỹ thuật).pdfOrient Homes
 
Tạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướng
Tạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướngTạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướng
Tạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướngMay Ong Vang
 
CATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdf
CATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdfCATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdf
CATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdfOrient Homes
 
CATALOGUE ART-DNA 2023-2024-Orient Homes.pdf
CATALOGUE ART-DNA 2023-2024-Orient Homes.pdfCATALOGUE ART-DNA 2023-2024-Orient Homes.pdf
CATALOGUE ART-DNA 2023-2024-Orient Homes.pdfOrient Homes
 
catalogue-cap-trung-va-ha-the-ls-vina.pdf
catalogue-cap-trung-va-ha-the-ls-vina.pdfcatalogue-cap-trung-va-ha-the-ls-vina.pdf
catalogue-cap-trung-va-ha-the-ls-vina.pdfOrient Homes
 
Dây cáp điện Trần Phú Eco - Catalogue 2023.pdf
Dây cáp điện Trần Phú Eco - Catalogue 2023.pdfDây cáp điện Trần Phú Eco - Catalogue 2023.pdf
Dây cáp điện Trần Phú Eco - Catalogue 2023.pdfOrient Homes
 
Catalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdf
Catalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdfCatalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdf
Catalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdfOrient Homes
 
CATALOG cáp cadivi_1.3.2024_compressed.pdf
CATALOG cáp cadivi_1.3.2024_compressed.pdfCATALOG cáp cadivi_1.3.2024_compressed.pdf
CATALOG cáp cadivi_1.3.2024_compressed.pdfOrient Homes
 
2020.Catalogue CÁP TR131321313UNG THẾ.pdf
2020.Catalogue CÁP TR131321313UNG THẾ.pdf2020.Catalogue CÁP TR131321313UNG THẾ.pdf
2020.Catalogue CÁP TR131321313UNG THẾ.pdfOrient Homes
 
Xu hướng tạp dề đồng phục hiện đại trong các ngành nghề
Xu hướng tạp dề đồng phục hiện đại trong các ngành nghềXu hướng tạp dề đồng phục hiện đại trong các ngành nghề
Xu hướng tạp dề đồng phục hiện đại trong các ngành nghềMay Ong Vang
 
Catalog Dây cáp điện CADIVI ky thuat.pdf
Catalog Dây cáp điện CADIVI ky thuat.pdfCatalog Dây cáp điện CADIVI ky thuat.pdf
Catalog Dây cáp điện CADIVI ky thuat.pdfOrient Homes
 
CATALOGUE Cáp điện Taya (FR, FPR) 2023.pdf
CATALOGUE Cáp điện Taya (FR, FPR) 2023.pdfCATALOGUE Cáp điện Taya (FR, FPR) 2023.pdf
CATALOGUE Cáp điện Taya (FR, FPR) 2023.pdfOrient Homes
 
Catalogue-thiet-bi-chieu-sang-DUHAL-2023.pdf
Catalogue-thiet-bi-chieu-sang-DUHAL-2023.pdfCatalogue-thiet-bi-chieu-sang-DUHAL-2023.pdf
Catalogue-thiet-bi-chieu-sang-DUHAL-2023.pdfOrient Homes
 
Catalog ống nước Europipe upvc-ppr2022.pdf
Catalog ống nước Europipe upvc-ppr2022.pdfCatalog ống nước Europipe upvc-ppr2022.pdf
Catalog ống nước Europipe upvc-ppr2022.pdfOrient Homes
 
Phân tích mô hình PESTEL Coca Cola - Nhóm 4.pptx
Phân tích mô hình PESTEL Coca Cola - Nhóm 4.pptxPhân tích mô hình PESTEL Coca Cola - Nhóm 4.pptx
Phân tích mô hình PESTEL Coca Cola - Nhóm 4.pptxtung2072003
 

Recently uploaded (15)

Catalogue cáp điện GOLDCUP 2023(kỹ thuật).pdf
Catalogue cáp điện GOLDCUP 2023(kỹ thuật).pdfCatalogue cáp điện GOLDCUP 2023(kỹ thuật).pdf
Catalogue cáp điện GOLDCUP 2023(kỹ thuật).pdf
 
Tạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướng
Tạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướngTạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướng
Tạp dề là gì? Tổng hợp các kiểu dáng tạp dề xu hướng
 
CATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdf
CATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdfCATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdf
CATALOG Đèn, thiết bị điện ASIA LIGHTING 2023.pdf
 
CATALOGUE ART-DNA 2023-2024-Orient Homes.pdf
CATALOGUE ART-DNA 2023-2024-Orient Homes.pdfCATALOGUE ART-DNA 2023-2024-Orient Homes.pdf
CATALOGUE ART-DNA 2023-2024-Orient Homes.pdf
 
catalogue-cap-trung-va-ha-the-ls-vina.pdf
catalogue-cap-trung-va-ha-the-ls-vina.pdfcatalogue-cap-trung-va-ha-the-ls-vina.pdf
catalogue-cap-trung-va-ha-the-ls-vina.pdf
 
Dây cáp điện Trần Phú Eco - Catalogue 2023.pdf
Dây cáp điện Trần Phú Eco - Catalogue 2023.pdfDây cáp điện Trần Phú Eco - Catalogue 2023.pdf
Dây cáp điện Trần Phú Eco - Catalogue 2023.pdf
 
Catalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdf
Catalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdfCatalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdf
Catalogue Cadisun CÁP HẠ THẾ (26-09-2020).pdf
 
CATALOG cáp cadivi_1.3.2024_compressed.pdf
CATALOG cáp cadivi_1.3.2024_compressed.pdfCATALOG cáp cadivi_1.3.2024_compressed.pdf
CATALOG cáp cadivi_1.3.2024_compressed.pdf
 
2020.Catalogue CÁP TR131321313UNG THẾ.pdf
2020.Catalogue CÁP TR131321313UNG THẾ.pdf2020.Catalogue CÁP TR131321313UNG THẾ.pdf
2020.Catalogue CÁP TR131321313UNG THẾ.pdf
 
Xu hướng tạp dề đồng phục hiện đại trong các ngành nghề
Xu hướng tạp dề đồng phục hiện đại trong các ngành nghềXu hướng tạp dề đồng phục hiện đại trong các ngành nghề
Xu hướng tạp dề đồng phục hiện đại trong các ngành nghề
 
Catalog Dây cáp điện CADIVI ky thuat.pdf
Catalog Dây cáp điện CADIVI ky thuat.pdfCatalog Dây cáp điện CADIVI ky thuat.pdf
Catalog Dây cáp điện CADIVI ky thuat.pdf
 
CATALOGUE Cáp điện Taya (FR, FPR) 2023.pdf
CATALOGUE Cáp điện Taya (FR, FPR) 2023.pdfCATALOGUE Cáp điện Taya (FR, FPR) 2023.pdf
CATALOGUE Cáp điện Taya (FR, FPR) 2023.pdf
 
Catalogue-thiet-bi-chieu-sang-DUHAL-2023.pdf
Catalogue-thiet-bi-chieu-sang-DUHAL-2023.pdfCatalogue-thiet-bi-chieu-sang-DUHAL-2023.pdf
Catalogue-thiet-bi-chieu-sang-DUHAL-2023.pdf
 
Catalog ống nước Europipe upvc-ppr2022.pdf
Catalog ống nước Europipe upvc-ppr2022.pdfCatalog ống nước Europipe upvc-ppr2022.pdf
Catalog ống nước Europipe upvc-ppr2022.pdf
 
Phân tích mô hình PESTEL Coca Cola - Nhóm 4.pptx
Phân tích mô hình PESTEL Coca Cola - Nhóm 4.pptxPhân tích mô hình PESTEL Coca Cola - Nhóm 4.pptx
Phân tích mô hình PESTEL Coca Cola - Nhóm 4.pptx
 

Tuan1_GioiThieu.pdf

  • 1. CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT DATA STRUCTURES AND ALGORITHMS ThS. Lê Quang Hòa – Bộ môn Toán - Tin Viện Toán ứng dụng và tin học
  • 2. NỘI DUNG ▪ Mục đích, yêu cầu ▪ Nội dung môn học ▪ Tài liệu tham khảo 2
  • 3. Mục đích ▪ Giới thiệu các kiến thức cơ bản về cấu trúc dữ liệu và các thuật toán ▪ Học cách sử dụng các cấu trúc dữ liệu như là một công cụ hỗ trợ việc phát triển các thuật toán ▪ Trình bày các thuật toán sắp xếp (sorting), tìm kiếm (searching), các thuật toán trên đồ thị (graphs) 3
  • 4. Mục tiêu ▪ Biết lựa chọn phương pháp lưu trữ dữ liệu thích hợp để cài đặt thuật toán giải các bài toán trong thực tế ứng dụng ▪ Biết cách tiếp cận để phát triển thuật toán giải các bài toán thực tế 4
  • 5. Nội dung ▪ Các khái niệm cơ bản ▪ Các sơ đồ thuật toán ▪ Các cấu trúc dữ liệu cơ bản ▪ Cây ▪ Đồ thị ▪ Sắp xếp ▪ Tìm kiếm 5
  • 6. Tài liệu tham khảo ▪ Robert Sedgewick. Algorithms in C++, Parts 1-4: Fundamentals, Data Structures, Sorting, Searching. 3th Edition, Addison-Wesley, 1999. ▪ 2. Robert Sedgewick. Algorithms in C++ Part 5: Graph Algorithms (3rd Edition). 3th Edition, Addison-Wesley, 2002. ▪ 3. Michael T. Goodrich, Roberto Tamassia, David M. Mount, Data Structures and Algorithms in C++. 704 pages. Wiley, 2003. ▪ 4. T.H. Cormen, C.E. Leiserson, R.L. Rivest. Introduction to Algorithms .Third Edition, MIT Press, 2009. (Có bản dịch tiếng Việt) ▪ 5. Nguyễn Đức Nghĩa. . Cấu trúc dữ liệu và thuật toán. NXB Đại học Bách khoa Hà nội, 2013. 368 trang. ▪ 6. Đỗ Xuân Lôi. Cấu trúc dữ liệu và giải thuật. NXB ĐH Quốc gia, Hà nội, 2005 6
  • 7. 1. Các khái niệm cơ bản 1.1 Ví dụ 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 7
  • 8. 1. Các khái niêm cơ bản 1.1 Ví dụ 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 8
  • 9. 1.1 Ví dụ: tìm dãy con tổng lớn nhất ( The maximum subarray problem) Cho dãy số gồm n số: , , … , , dãy gồm liên tiếp các số , , … , với 1 ≤ ≤ ≤ là dãy con của dãy đã cho, tìm tổng lớn nhất của các dãy con, dãy con có tổng lớn nhất gọi là dãy con lớn nhất Ví dụ cho dãy -1, 11, -4, 13, -5, 2 thì dãy con lớn nhất là 11, -4, 13 với tổng lớn nhất các dãy con là 11+(-4) + 13=20 9
  • 10. Một số cách giải ▪ Duyệt toàn bộ(brute force) ▪ Duyệt toàn bộ cải tiến ▪ Thuật toán đệ quy (Recursive algorithm) ▪ Thuật toán quy hoạch động (Dynamic programming) 10
  • 11. Duyệt toàn bộ (brute force) ▪ Thuật toán đơn giản là: tìm tất cả các dãy con có thể : , , … , với 1 ≤ ≤ ≤ và tính tổng của mỗi dãy con để tìm ra tổng lớn nhất. ▪ tổng số các dãy con có thể của dãy đã cho là: , 1 + , 2 = + 11
  • 12. Duyệt toàn bộ (brute force) 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
  • 13. Duyệt toàn bộ (brute force) ▪ Phân tích tuật toán: số phép cộng phải thực hiện là số lần thực hiện lệnh sum+=a[k] ▪ Số phép cộng là: ▪ ∑ ∑ − + 1 = ∑ (1 + 2+. . +( − ) = ∑ ( ( )( ) )= ∑ ( + 1) = + = + + 13
  • 14. Duyệt toàn bộ (brute force) 14 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)
  • 15. Duyệt toàn bộ cải tiến ▪ Nhận xét tổng các phần tử từ vị trí i đến j sẽ bằng tổng các phần tử từ i đến j-1 cộng với a[j] ▪ Ta cải tiến thuật toán như sau: 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; } } 15
  • 16. Duyệt toàn bộ cải tiến ▪ Phân tích tuật toán: số phép cộng phải thực hiện là số lần thực hiện lệnh sum+=a[j] ▪ Số phép cộng là: ▪ ∑ ( − ) = + − 1 + ⋯ + 1 = + ▪ Số phép cộng đúng bằng số lượng dãy con, vậy còn thuật toán nào tốt hơn không? 16
  • 17. Thuật toán đệ quy ▪ Thuật toán đệ quy dùng kỹ thuật chia để trị (divide and conquer) gồm các bước: 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 oTrườ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 17
  • 18. Thuật toán đệ quy ▪ Để 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 18
  • 19. Thuật toán đệ quy ▪ Để 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 19
  • 20. Thuật toán đệ quy ▪ Do đó, nếu kí hiệu tổ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
  • 21. Thuật toán đệ quy maxSub(a, low,high); { if(low=high) return a[low] Else { mid=(low+high)/2; wL=maxSub(a, low,mid); wR=maxSub(a, mid,high); wM=maxCrossMidPoint(a,low,mid,high); return max(wL,wR,wM);} } 21
  • 22. Thuật toán đệ quy Việc tìm tổ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 tổ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 tổ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 tổng wMR của dãy con lớn nhất bắt đầu ở vị trí mid+1 – Khi đó wM = wML + wMR. 22
  • 23. Thuật toán đệ quy Ở dãy nửa trái: tìm tổ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 tổng wMR của dãy con lớn nhất bắt đầu ở vị trí mid+1 Khi đó wM = wML + wMR 23
  • 24. Ví dụ tính tổng wM của dãy con lớn nhất bắt đầu ở nửa dãy trái và kết thúc ở nửa dãy phải 24
  • 25. Thuật toán đệ quy 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 2 + 2 + = 2 2 + = 1 > 1 Giải ra ta được T(n)=nlogn 25
  • 26. Thuật toán đệ quy Ta khẳng định rằng T(2k) = k.2k. Ta chứng minh bằng qui nạp • Cơ sở qui nạp: Nếu k=0 thì T(20) = T(1) = 0 = 0.20. • Chuyển qui nạp: Nếu k>0, giả sử rằng T(2k-1) = (k-1)2k-1 là đúng. Khi đó T(2k) = 2T(2k-1)+2k = 2(k-1).2k-1 + 2k = k.2k. • Quay lại với ký hiệu n, ta có T(n) = n log n 26
  • 27. Thuật toán đệ quy 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 Ta sẽ phải gọi lệnh: MaxSub(a, 1, 10) 27 1 2 3 4 5 6 7 8 9 10 13 -3 -25 20 -3 -16 -23 18 20 -7
  • 28. So sánh số phép tính 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 28
  • 29. So sánh số phép tính các thuật toán 29 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?
  • 30. Thuật toán Quy hoạch động (Dynamic programming) 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) 30
  • 31. Thuật toán Quy hoạch động (Dynamic programming) 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) 31
  • 32. Ví dụ 1. Phân rã: • Gọi si là tổng của dãy con lớn nhất của dãy a1, a2, ..., ai , i = 1, 2, ..., n. • Rõ ràng, sn là 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: • s1 = a1 • Giả sử i > 1 và ta đã biết giá trị sk với k = 1, 2, ..., i-1. Ta cần tính giá trị si là tổng của dãy con lớn nhất của dãy: a1, a2, ..., ai-1 , ai 32
  • 33. Ví dụ Nhận thấy rằng: dãy con lớn nhất của dãy a1, a2, ..., ai-1, ai có thể hoặc bao gồm phần tử ai hoặc không bao gồm phần tử ai, do đó, dãy con lớn nhất của dãy a1, a2, ..., ai-1, ai chỉ có thể là một trọng 2 dãy sau: – 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, ..., ai , và dãy con này kết thúc tại phần tử ai. Do đó, ta có si = max {si-1, ei}, i = 2, …, n. với ei là tổng của dãy con lớn nhất a1, a2, ..., ai và dãy con này kết thúc tại ai. Để tính ei, ta xây dựng công thức đệ quy: – e1 = a1; – ei = max {ai, ei-1 + ai}, i = 2, ..., n. 33
  • 34. Ví dụ MaxSub(a) { smax=a[1]; ei=a[1]; imax=1; 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;}} } 34
  • 35. Ví dụ Smax=13, ei=13, imax=1 i=2 ei=10 i=3 ei=-15 i=4 ei=20 smax=20 imax=4 i=5 ei=17 i=6 ei=1 i=7 ei=-22 i=8 ei=18 i=9 ei=38 smax=38 imax=9 i=10 ei=31 35 1 2 3 4 5 6 7 8 9 10 13 -3 -25 20 -3 -16 -23 18 20 -7
  • 36. So sánh bốn 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) 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 36
  • 37. 1. Các khái niêm cơ bản 1.1 Ví dụ 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 37
  • 38. Thuật toán (Algorithm) Trong 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 38
  • 40. Ví dụ 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: 13 • Yêu cầu: thiết kế thuật toán giải bài toán trên 40
  • 41. Tìm số lớn nhất dãy sau 41
  • 42. Các bước thực hiện 42
  • 45. Thuật toán (Algorithm) 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. 45
  • 46. Thuật toán (Algorithm) – 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 46
  • 47. Cấu trúc dữ liệu Cấu trúc dữ liệu là cách lưu trữ, tổ chức dữ liệu có thứ tự, có hệ thống để dữ liệu có thể được sử dụng một cách hiệu quả • Interface: Mỗi cấu trúc dữ liệu có một Interface. Interface biểu diễn một tập hợp các phép tính mà một cấu trúc dữ liệu hỗ trợ. Một Interface chỉ cung cấp danh sách các phép tính được hỗ trợ, các loại tham số mà chúng có thể chấp nhận và kiểu trả về của các phép tính này. • Implementation (có thể hiểu là sự triển khai): Cung cấp sự biểu diễn nội bộ của một cấu trúc dữ liệu. Implementation cũng cung cấp phần định nghĩa của giải thuật được sử dụng trong các phép tính của cấu trúc dữ liệu 47
  • 48. Đặc điểm cấu trúc dữ liệu • Chính xác: Sự triển khai của Cấu trúc dữ liệu nên triển khai Interface của nó một cách chính xác. • Độ phức tạp về thời gian (Time Complexity): Thời gian chạy hoặc thời gian thực thi của các phép tính của cấu trúc dữ liệu phải là nhỏ nhất có thể. • Độ phức tạp về bộ nhớ (Space Complexity): Sự sử dụng bộ nhớ của mỗi phép tính của cấu trúc dữ liệu nên là nhỏ nhất có thể 48
  • 49. Cần thiết có cấu trúc dữ liệu • Tìm kiếm dữ liệu: Giả sử có 1 triệu hàng hóa được lưu giữ vào trong kho hàng hóa. Và giả sử có một ứng dụng cần để tìm kiếm một hàng hóa. Thì mỗi khi thực hiện tìm kiếm, ứng dụng này sẽ phải tìm kiếm 1 hàng hóa trong 1 triệu hàng hóa. Khi dữ liệu tăng lên thì việc tìm kiếm sẽ càng trở lên chậm và tốn kém hơn. • Tốc độ bộ vi xử lý: Mặc dù bộ vi xử lý có tốc độ rất cao, tuy nhiên nó cũng có giới hạn và khi lượng dữ liệu lên tới hàng tỉ bản ghi thì tốc độ xử lý cũng sẽ không còn được nhanh nữa. • Đa yêu cầu 49
  • 50. Giải bài toán là gì Problem solving – Là quá trình đặt bài toán và phát triển chương trình máy tính để giải bài toán đặt ra • Lời giải bài toán bao gồm: – Thuật toán (Algorithms) • Algorithm: là dãy các bước cần thực hiện để từ dữ liệu vào (input) đưa ra kết quả đầu ra (output) của bài toán trong thời gian hữu hạn. – Cấu trúc dữ liệu (Data structures): • Cách tổ chức lưu trữ dữ liệu vào - ra 50
  • 51. Vòng đời của phần mềm (The Life Cycle of Software) Vòng đời của phần mềm – Là một quá trình dài và liên tục – Đòi hỏi để phát triển một phần mềm có chất lượng tốt – Lập trình viên có thể di chuyển từ một pha trong vòng đời sang bất kỳ pha nào còn lại 51
  • 52. Vòng đời của phần mềm (The Life Cycle of Software) 9 pha: • Phase 1: Chỉ rõ đặc điểm kỹ thuật (Specification) (đặc tả) • Phase 2: Thiết kế (Design) • Phase 3: Phân tích rủi ro (Risk Analysis) • Phase 4: Kiểm thử (Verification) • Phase 5: Lập trình (Coding) • Phase 6: Test thử (Testing) • Phase 7: Tinh chế lời giải (Refining the Solution) • Phase 8: Sản xuất (Production) • Phase 9: Bảo trì (Maintenance) 52
  • 53. Vòng đời của phần mềm (The Life Cycle of Software) Phase 1: Đặc tả (Specification) – Các khía cạnh của bài toán cần chỉ rõ: • Dữ liệu đầu vào là gì (What is the input data?) • Dữ liệu nào là đúng đắn, là không đúng đắn? • Ai là người sử dụng phần mềm và giao diện người dùng cần được thiết kế như thế nào? • Cần phát hiện những lỗi gì và cần thông báo như thế nào về chúng? • Có thể có các giả thiết nào? • Có những trường hợp đặc biệt nào? • Dạng của dữ liệu đưa ra như thế nào? • Cần có các tài liệu gì? • Cái gì cần phát triển trong tương lai? – Chương trình mẫu (Chương trình mô phỏng dáng điệu của một phần của sản phẩm phần mềm cần phát triển) 53
  • 54. Vòng đời của phần mềm (The Life Cycle of Software) Phase 2: Thiết kế (Design). Quá trình thiết kế bao gồm: – Chia chương trình ra thành các modules (Modules: là các đơn vị chương trình độc lập) – Chỉ rõ mục đích của mỗi module – Chỉ rõ dòng dữ liệu trong các modules – Xác định giao diện (Interfaces - Cơ cấu giao tiếp giữa các mô đun) 54
  • 55. Vòng đời của phần mềm (The Life Cycle of Software) Phase 3: Phân tích rủi ro (Risk Analysis) Phase 4: Kiểm thử (Verification) – Chứng minh tính đúng đắn của thuật toán bằng các phương pháp hình thức, … Phase 5: Cài đặt (Coding) – Liên quan đến việc chuyển thiết kế sang một ngôn ngữ lập trình cụ thể – Loại trừ các lỗi ngữ pháp 55
  • 56. Vòng đời của phần mềm (The Life Cycle of Software) Phase 6: Test thử (Testing) – Liên quan đến việc loại bỏ các lỗi logic – Dữ liệu test phải bao gồm: • Dữ liệu đúng đắn với kết quả biết trước • Dữ liệu không đúng đắn • Dữ liệu ngẫu nhiên • Dữ liệu thực tế 56
  • 57. Vòng đời của phần mềm (The Life Cycle of Software) Phase 7: Tinh chế lời giải (Refining the Solution) – Do chương trình được phát triển với những giả thiết nhất định nên cần tìm cách giảm nhẹ các giả thiết được bổ sung đối với đầu vào, đầu ra – Bổ sung thêm các chức năng – Tăng các biện pháp kiểm tra lỗi 57
  • 58. Vòng đời của phần mềm (The Life Cycle of Software) • Phase 8: Xuất xưởng (Production) – Bàn giao sản phẩm cho người dùng. – Người dùng sử dụng phần mềm • Phase 9: Bảo trì (Maintenance) – Sửa chữa các lỗi do người sử dụng phát hiện. – Bổ sung thêm chức năng. – Cải tiến một số bộ phận để đáp ứng yêu cầu của người dùng tốt hơn 58
  • 59. 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 59
  • 60. Ví dụ: Xây dựng thuật toán giải bài toán 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 60
  • 61. Đặt vấ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Ớ 61
  • 62. Độ phức tạp của thuật toán Đánh giá độ phức tạp tính toán của thuật toán là đánh giá lượng tài nguyên các loại mà thuật toán đòi hỏi sử dụng. Có hai loại tài nguyên quan trọng đó là thời gian và 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. • Thời gian tính phụ thuộc vào dữ liệu vào. • Đị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ó. • 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 vào. 62
  • 63. Độ phức tạp của thuật toán 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). 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 63
  • 64. Độ phức tạp của thuật toán • 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) Vậy ta có 3 loại thời gian tính 64
  • 65. Độ phức tạp của thuật toán 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 65
  • 66. Độ phức tạp của thuật toán 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. • Dễ xác định Có hai cách để đánh giá thời gian tính: • Từ thời gian chạy thực nghiệm • Lý thuyết: khái niệm xấp xỉ tiệm cận 66
  • 67. 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 • Đo thời gian chạy trung bình • Vẽ đồ thị kết quả 67
  • 68. 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ắt 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 dẫn đến rất khó khăn và tốn nhiều chi phí. 68
  • 69. 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 • Để 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 69
  • 70. 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) 70
  • 71. Phép toán cơ bản • Đo thời gian tính bằng đơn vị đo nào? • Định nghĩa. Ta gọi phép toán cơ bản là phép toán có thể thực hiện với thời gian bị chặn bởi một hằng số không phụ thuộc vào kích thước dữ liệu. • Để tính toán thời gian thực hiện của thuật toán ta sẽ đếm số phép toán cơ bản mà nó phải thực hiện. 71
  • 72. 1. Các khái niêm cơ bản 1.1 Ví dụ 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 72
  • 73. Kí hiệu tiệm cận (Asymptotic notation) 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 73
  • 74. 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ă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 các hằng số dương c1,c2 sao cho nó bị kẹp giữa c1g(n) và c2g(n) với giá trị n đủ lớn Ta nói g(n) đánh giá tiệm cận đúng cho f(n) và viết f(n)= Θ(g(n)) 74
  • 76. Kí hiệu Theta Ví dụ 1: chứng minh rằng 10n2-3n= Θ(n2) Ta cần chỉ ra với các giá trị nào của n0,c1,c2 thì bất đẳng thức trong định nghĩa của ký hiệu theta là đúng c1 n2 ≤ f(n) = 10n2-3n ≤ c2 n2 với mọi n≥ n0 Gợi ý: lấy c1 nhỏ hơn số hạng với số mũ cao nhất, c2 lớn hơn Chọn c1=1, c2=11, n0=1 76
  • 77. Kí hiệu Theta Ví dụ 2: chứng minh rằng n2-3n= Θ(n2) Ta cần chỉ ra với các giá trị nào của n0,c1,c2 thì bất đẳng thức trong định nghĩa của ký hiệu theta là đúng c1 n2 ≤ f(n) = n2-3n ≤ c2 n2 với mọi n≥ n0 Gợi ý: lấy c1 nhỏ hơn số hạng với số mũ cao nhất, c2 lớn hơn Chọn c1=1/4, c2=1, n0=7 77
  • 78. 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 Θ(g(n)) ={f(n): tồn tại các hằng số dương c và n0 sao cho 0≤ f(n) ≤ cg(n), với mọi n≥ n0} (tập tất cả các hàm có độ tăng nhỏ hơn hoặc bằng tốc độ tăng của g(n) Hàm f(n) thuộc vào tập O(g(n)) nếu tồn tại các hằng số dương c sao cho f(n) ≤ cg(n) với giá trị n đủ lớ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)) 78
  • 79. Kí hiệu O lớn (big Oh) 79
  • 80. Kí hiệu O lớn (big Oh) Ví dụ 1: Chứng minh rằng 2n + 10 = O(n) Ví dụ 2: Chứng minh rằng 7n - 2 = O(n) Ví dụ 3: Chứng minh rằng 3n3 + 20n2 + 5 = O(n3) Ví dụ 4: Chứng minh rằng 3 log2n + 5 = O(log2n) 80
  • 81. Một số quy tắc O lớn Nếu f(n) là đa thức bậc d thì f(n)=O(nd) tức là o Bỏ qua các số hạng có số mũ thấp hơn d o Bỏ qua các hằng số Nên tìm hàm g(n) có tốc độ tăng càng chậm càng tốt o Sử dụng các lớp hàm có tốc độ tăng nhỏ nhất có thể o Sử dụng hàm đơn giản nhất có thể 81
  • 82. 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 và n0 sao cho 0≤ cg(n) ≤ f(n), với mọi n≥ n0} (tập tất cả các hàm có độ tăng lớn hơn hoặc bằng tốc độ tăng của g(n) Hàm f(n) thuộc vào tập Ω(g(n)) nếu tồn tại các hằng số dương c sao cho cg(n) ≤ f(n) với giá trị n đủ lớn Ta nói g(n) là cận dưới tiệm cận của f(n) và viết f(n)= Ω(g(n)) 82
  • 84. Các ký hiệu tiệm cận 84
  • 85. Các ký hiệu tiệm cận Định lý: đối với hai hàm g(n) và f(n) bất kỳ, ta có f(n)= (g(n)) khi và chỉ khi f(n)=O(g(n)) và f(n)=Ω (g(n)) 85
  • 86. 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)) 86
  • 87. 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 87
  • 88. 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) 88
  • 89. 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 Ví dụ: Thuật toán sắp xếp chèn (Insertion sorting) có thời gian trung bình cỡ n2 89
  • 90. Một số lớp thuật toán cơ bản ▪ Hằng số ≈ (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) ▪ Đa thức (polynomial) ≈ O(nk), n>=1 ▪ Hàm mũ (exponential) ≈ O(an), a>1 90
  • 91. Một số lớp thuật toán cơ bản Những hàm nào trong số những hàm sau giống nhau hơn? n1000 n2 2n 1000n2 3n2 2n3 91
  • 92. Tốc độ tăng của một số hàm cơ bản 92
  • 93. 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 93
  • 94. Phân loại thời gian tính của thuật toán – 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 và k là các hằng số tương ứng 94
  • 95. 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 là 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ó cận trên là O(g(n)) và cận dưới là Ω(g(n)) 95
  • 96. Cách nhớ các kí hiệu 96
  • 97. Chú ý • Giả sử có 2 thuật toán: • Thuật toán A có thời gian chạy 30000n • Thuật toán B có thời gian chạy 3n2 • 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 97
  • 98. 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, ... 98
  • 99. Bài toán dễ giải, khó giải và không giải được • 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 99
  • 100. 1. Các khái niêm cơ bản 1.1 Ví dụ 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 100
  • 101. 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 language), cho phép: – Mô 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 kê một số câu lệnh chính được sử dụng trong giáo trình để mô tả thuật toán 101
  • 102. 1.4. Giả ngôn ngữ (Pseudocode) 102
  • 103. 1.4. Giả ngôn ngữ (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; 103
  • 104. 1.4. Giả ngôn ngữ (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; 104
  • 105. 1.4. Giả ngôn ngữ (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; 105
  • 106. 1.4. Giả ngôn ngữ (Pseudocode) ▪ Vào/ra: read(X); /* X là biến */ print(data); hoặc print(thông báo); • Hàm và thủ tục: Function name(arguments) begin khai báo biến; các câu lệnh trong hàm; return (value); end; 106
  • 107. 1.4. Giả ngôn ngữ (Pseudocode) Procedure name(arguments) begin khai báo biến; các câu lệnh trong thủ tục; end; 107
  • 108. 1. Các khái niêm cơ bản 1.1 Ví dụ 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 108
  • 109. 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 dẫn đến rất khó khăn và tốn nhiều chi phí. 109
  • 110. Tính toán thời gian tính của thuật toán • Để 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 vậy, ta cần đánh giá thuật toán theo hướng xấp xỉ tiệm cận 110
  • 111. Tính toán thời gian tính của thuật toá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à 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. 111
  • 112. 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 phép toán cơ bản là phép toán có thể thực hiện với thời gian bị chặn bởi 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) 112
  • 113. 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, Q là hai đoạn chương trình thực thi một thuật toán P thực hiện xong đến Q: time(P,Q)=time(P)+time(Q) 2. Vòng lặp for: for i=1 to m do P(i) Với thời gian thực hiện P(i) là t(i): time(for)=∑ ( ) 3. 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)) 113
  • 114. Phân tích độ phức tạp của thuật toán: Các kĩ thuật cơ bản 4. 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. 114