Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Chương 2 Độ phức tạp của một số thuật
toán điển hình
Nguyễn Văn HạnhBộ môn Toán -tin ứng dụng
Email: [email protected]: http://fita.vnua.edu.vn/nvhanh/
Nội dung
1. Thuật toán chia để trị
2. Thuật toán quy hoạch động
3. Thuật toán tham lam
1. Thuật toán chia để trị
1. Ý tưởng
2. Sơ đồ chung thuật toán
3. Một số bài toán minh hoạ
Ý tưởng
• Để giải quyết vấn đề phức tạp, ta chia vấn đề thành nhiều vấn đề con nhỏ hơn, đơn giản hơn.
• Giải quyết từng vấn đề nhỏ và kết hợp kết quả của chúng lại (nếu cần) để thu được lời giải của bài toán nguyên thuỷ.
• Một số ví dụ
Phân nhỏ công việc cần làm
Phân nhỏ đồ vật
Sáng tạo: phân nhỏ không gian ruột xe, phân nhỏ quãng đường
Các bước thực hiện
• Chia (Divide): chia bài toán ban đầu thành một số bài toán con
• Trị (Conquer): giải quyết các bài toán con một cách đệ quy. Nếu
kích thước của bài toán con đủ nhỏ thì có thể giải trực tiếp.
• Kết hợp (Combine): kết hợp lời giải của các bài toán con thành lời
giải của bài toán ban đầu (có thể không cần bước này)
Sơ đồ tổng quát thuật toán chia để trị
Procedure D_and_C(n)
Begin
If then
Giải bài toán một cách trực tiếp
Else
1. Chia bài toán thành r bài toán con kích thước
2. For (mỗi bài toán trong r bài toán con) Do
D_and_C( )
3. Tổng hợp lời giả của r bài toán con để thu được lời giải của bài toán gốc
End;
n ≤ n0
n /k
n /k
Độ phức tạp thuật toán chia để trị
• Gọi là độ phức tạp thuật toán D_and_C(n).
• Với thì
• Với , chia bài toán thành bài toán con, gọi đệ quy để giải bài toán con có độ phức tạp , độ phức tạp chia và tổng hợp là
• Công thức đệ quy để xác định độ phức tạp thuật toán chia để trị là
Định lý tổng quát (Master theorem): Nếu thì
T(n)
n ≤ n0 T(n) = α
n > n0 r rrT(n /k) g(n)
T(n) = {α, if n ≤ n0
rT(n /k) + g(n), if n > n0
g(n) = cnβ
T(n) ∈O(nβ), if r < kβ
O(nβlogn), if r = kβ
O(nlogkr), if r > kβ
Một số bài toán minh hoạ
• Tìm kiếm nhị phân
• Sắp xếp kiểu hoà nhập (Merge Sort)
Tìm kiếm nhị phân
• Bài toán: Cho mảng được sắp xếp theo thứ tự không giảm và số
Tìm sao cho
• Ý tưởng:
Chia (Divide): xác định phần tử giữa dãy. Nếu phần tử cần tìm bằng phần tử này
thì trả về vị trí tìm được và kết thúc. Nếu phần tử cần tìm nhỏ hơn phần tử này thì
ta chỉ cần tìm trong dãy con bên trái. Nếu phần tử cần tìm lớn hơn phần tử này thì
ta chỉ cần tìm trong dãy con bên phải.
Trị (Conquer): Tiếp tục tìm kiếm trong các dãy con đến khi tìm thấy hoặc đến khi
hết dãy.
Kết hợp (Combine): Không cần trong bài toán này.
A[1…n]
y . i A[i] = y .
Tìm kiếm nhị phân
• Bài toán: Cho mảng được sắp xếp theo thứ tự không giảm và số
Tìm sao cho
• Giải thuật:
Function Binary_search(A, y, start, finish)
Begin
Mid : = (start + finish)/2;
If (y = A[Mid]) then return Mid
Else
If (y < A[Mid]) then
Return Binary_search(A, y, start, Mid - 1)
Else
Return Binary_search(A, y, Mid + 1, finish)
End;
A[1…n] y .
i A[i] = y .
Độ phức tạp thuật toán tìm kiếm nhị phân
• Gọi là độ phức tạp thuật toán Binary_search.
• Công thức đệ quy để xác định độ phức tạp thuật toán trên là
• Theo định lý tổng quát thì
• Chú ý: nếu thực hiện thuật toán so sánh với từng phần tử của mảng thì độ phức tạp là
T(n)
T(n) = {C, if n = 1T(n/2) + C, if n > 1
T(n) = O(logn)
yA O(n) .
Một số bài toán minh hoạ
• Tìm kiếm nhị phân
• Sắp xếp kiểu hoà nhập (Merge Sort)
Bài toán sắp xếp
• Bài toán sắp xếp: Cho là một mảng n phần tử. Vấn đề đặt ra là
sắp xếp các phần tử này theo thứ tự không giảm
• Các thuật toán giải quyết:
Sắp xếp kiểu hoà nhập (Merge Sort):
Sắp xếp kiểu lựa chọn (Selection Sort):
Sắp xếp kiểu thêm dần (Insertion Sort):
Sắp xếp kiểu vun đống (Heap Sort):
Sắp xếp nhanh (Quick Sort):
A[1…n]
O(nlogn)
O(n2)
O(n2)
O(nlogn)
O(nlogn)
Sắp xếp kiểu hoà nhập (Merge Sort)
Sắp xếp kiểu hoà nhập (Merge Sort):
• Ý tưởng:
Chia (Divide): Chia dãy phần tử cần sắp xếp thành 2 dãy con, mỗi dãy có
phần tử.
Trị (Conquer): Sắp xếp các dãy con bằng cách gọi đệ quy Merge_Sort. Dãy con
chỉ có một phần tử thì mặc nhiên có thứ tự, không cần sắp xếp.
Kết hợp (Combine): Trộn 2 dãy con đã sắp xếp để tạo thành dãy ban đầu có
thứ tự.
• Chú ý: Khi nhỏ ta thường sử dụng các thuật toán sắp xếp đơn giản. Khi
lớn thì ta dùng thuật toán chia để trị (sắp xếp kiểu hoà nhập).
n
n /2
n n
Sắp xếp kiểu hoà nhập (Merge Sort)
• Thuật toán:
Procedure Merge_Sort( );
Begin
If đủ nhỏ then Insert(A)
Else
Begin
Array ;
Merge_Sort( );
Merge_Sort( );
Merge(U, V, A);
End;
End;
A[1…n]
n
U[1…1 + [n /2]], V[1…1 + [n /2]]
U[1…1 + [n /2]] := A[1…1 + [n /2]];
V[1…1 + [n /2]] := A[1 + [n /2]…n];
U[1…[n /2]]
V[1…[n /2]]
Sắp xếp kiểu hoà nhập (Merge Sort)
• Thuật toán trộn hai mảng:
Procedure Merge( , , )
Begin
For to do
If then
Begin
`
End;
Else
Begin
`
End;
End;
U[1…m + 1] V[1…n + 1] A[1…m + n]
i := 1; j := 1;
U[m + 1] := ∞; V[n + 1] := ∞;
k := 1 n + m
U[i] < V[ j]
A[k] := U[i];
i := i + 1;
A[k] := U[ j];
j := j + 1;
Độ phức tạp thuật toán sắp xếp kiểu hoà nhập
• Gọi là độ phức tạp thuật toán Merge_Sort.
• Chia (Divide): độ phức tạp là hằng số để tính phần tử giữa dãy.
• Trị (Conquer): Giải quyết đệ quy 2 dãy con, mỗi dạy có kích thước , nên độ phức tạp là
• Kết hợp (Combine): Giải thuật trộn n phần tử có độ phức tạp là
T(n)
O(1)
n/2 2T(n/2)
O(n)
Độ phức tạp thuật toán sắp xếp kiểu hoà nhập
• Gọi là độ phức tạp thuật toán Merge_Sort.
• Công thức đệ quy để xác định độ phức tạp thuật toán trên là
• Theo định lý tổng quát thì
T(n)
T(n) = {O(1), if n = 12T(n/2) + O(n), if n > 1
T(n) = O(nlogn)
Tổng kết thuật toán chia để trị
• Chia để trị chỉ là một trong những phương pháp thiết kế thuật
toán.
• Thuật toán chia để trị có thể được phân tích dựa trên quy nạp
và phương pháp định lý tổng quát.
• Thông thường phương pháp chia để trị khá hiệu quả.
Chapter 2 (To be continued)