You are on page 1of 27

Độ phức tạp thuật toán

Cấu trúc dữ liệu và giải thuật


Bùi Duy Đăng
bddang@fit.hcmus.edu.vn
Thuật toán là gì?
• Là chuỗi hữu hạn các bước cơ bản để giải quyết vấn đề
• Nêu thuật toán cho các bài toán sau:
• Cho một mảng có n phần tử, tìm phần tử nhỏ nhất
• Cho một mảng có n phần tử, tìm phần tử k
• Cho một mảng có n phần tử tăng dần, tìm phần tử k
• Sắp xếp một mảng có n phần tử, sao cho số lẻ được sắp xếp tăng dần
bên trái, số chẳn được sắp xếp giảm dần bên phải

Nhập môn lập trình 2


So sánh thuật toán
• Giải quyết bài toán X • Giải quyết bài toán X
• Thuật toán A • Thuật toán B
• Máy tính A1, có cấu hình A2 • Máy tính B1, có cấu hình B2
• Người lập trình A3 • Người lập trình B3

Các yếu tố để đánh giá một thuật toán?

Nhập môn lập trình 3


Chi phí đánh giá thuật toán
• Thời gian
• Thời gian chạy thuật toán

• Bộ nhớ
• Bộ nhớ để lưu trữ cho thuật toán

Nhập môn lập trình 4


Chi phí đánh giá thuật toán

Weighing about three pounds, each reel could Able to hold 550 megabytes Later versions increased the capacity of
hold 1,440,000 decimal digits and could be read of pre-recorded data a single disk from 100MB to 2GB
at 100 inches/sec.
1951 1984-1985 ~2000

Ngày nay, bộ nhớ ít được quan tâm khi đánh giá thuật toán

Nhập môn lập trình 5


Chi phí đánh giá thuật toán
• Giải quyết bài toán X • Giải quyết bài toán X
• Thuật toán A • Thuật toán B
• Máy tính A1, có cấu hình A2 • Máy tính B1, có cấu hình B2
• Người lập trình A3 • Người lập trình B3
• Thời gian chạy A4 • Thời gian chạy B4

A4 và B4 có thể so So sánh một cách độc


sánh được không? lập với các yếu tố trên?

Nhập môn lập trình 6


Làm sao để đánh giá thuật toán?
• Đếm số lượng thao tác cơ bản (basic operations)
• Tốn nhiều thời gian thực thi
• Thao tác cơ bản
• So sánh
• Tính toán
• Gán

Nhập môn lập trình 7


Ví dụ
• Xác định thao tác cơ bản
• Đếm số lượng thao tác cơ bản
• Số phép gán:
• Số phép so sánh:
• Số phép tính toán:

Nhập môn lập trình 8


Ví dụ
• Xác định thao tác cơ bản
• Đếm số lượng thao tác cơ bản
• Số phép gán:
• Số phép so sánh:
• Số phép tính toán:

Nhập môn lập trình 9


Ví dụ
• Xác định thao tác cơ bản
• Đếm số lượng thao tác cơ bản
• Số phép gán:
• Số phép so sánh:
• Số phép tính toán:

Nhập môn lập trình 10


Chi phí thuật toán
• So sánh thuật toán khi n đủ lớn
• Quan tâm những thay đổi lớn
• Bỏ qua yếu tố phụ (không đáng kể)
f(n)=1000n2 + 100n + log n + 1000

Nhập môn lập trình 11


Các hàm tăng trưởng
f(n) Tên gọi
1 (hằng số) Constant time
logn (logarit) Logarithmic time
n (tuyến tính) Linear time
nlogn (tuyến tính logarit) Linearithmic time
nk (đa thức) Polynominal time
2n (mũ) Exponential time
n! (giai thừa) Factorial time

Nhập môn lập trình 12


Các hàm tăng trưởng

Nhập môn lập trình 13


Chi phí thuật toán
• Trường hợp tốt nhất (best case)
• Không phản ánh thực tế

• Trường hợp trung bình (everage case)


• Rất khó tính toán

• Trường hợp xấu nhất (worst case)


• Thường được sử dụng
• “Bảo đảm tuyệt đối”

Nhập môn lập trình 14


Ví dụ
• Tìm phần tử k trong mảng có n phần tử bất kì.
• Trường hợp tốt nhất
• Trường hợp xấu nhất
• Trường hợp trung bình
• Giả sử xác suất k xuất hiện là p
• Giả sử n phần tử khác nhau

Nhập môn lập trình 15


Big O
• Cho f(n) và g(n) là hai hàm số, n→∞

f là big O của g nếu tồn tại số dương c sao cho f không thể lớn
hơn c*g khi n đủ lớn

• g(n) là giới hạn trên (upper bound) của f(n);


• Khi n lớn, f(n) tăng tương đương bằng g(n)

Nhập môn lập trình 16


Big O

Khi n đủ lớn (n>=n0), thì g(n) là giới hạn trên của f(n)
Nhập môn lập trình 17
Big O
• Ví dụ: f(n)= 4n2 + 5n + 1
• g(n) = n2, O(g(n)) = n2
• Chọn c = 5 và n0 = 6
• Với mọi n >= 6 à f(n) < 5*g(n)

Nhập môn lập trình 18


Big O
• Khi áp dụng big-O vào việc ước lượng độ phức tạp của giải
thuật, ta nên chọn g(n):
• Càng đơn giản càng tốt
• Bỏ qua các hằng số và các thành phần có lũy thừa thấp

Nhập môn lập trình 19


Ví dụ
• Trắc nghiệm 1: xác định O(g(n)) của các hàm sau đây
• f(n) = 10
• f(n) = 6n + 1
• f(n) = 10n3 – 3n + 20
• f(n) = logn + 100
• f(n) = nlogn + logn + 5
• Trắc nghiệm 2: phát biểu nào sau đây là đúng?
• 2n+1 = O(2n)
• 22n = O(2n)

Nhập môn lập trình 20


Big Ω
• Big Ω

f là big Ω của g nếu tồn tại số dương c sao cho f lớn hơn c*g khi
n đủ lớn

• g(n) là giới hạn dưới (lower bound) của f(n);

Nhập môn lập trình 21


Big Θ
• Big Θ

f là big Θ của g nếu tồn tại số dương c1, c2 sao cho f ở giữa
c1 *g và c1*g khi n đủ lớn

• g(n) là giới hạn chặt (tight bound) của f(n);

Nhập môn lập trình 22


Phân tích độ phức tạp hàm phi đệ quy
1. Xác định kích thước đầu vào
2. Xác định thao tác cơ sở
3. Kiểm tra số lần thao tác cơ sở được thực hiện phụ thuộc vào kích
thước đầu vào. Nếu nó phụ thuộc vào yếu tố khác như worst case,
everage case, best case, thì thực hiện riêng biệt từng trường hợp
4. Thiết lập biểu thức tính tổng số lần thao tác sơ sở được thực thi
5. Tìm công thức đếm và thiết lập độ tăng trưởng của công thức

Nhập môn lập trình 23


Ví dụ
BubbleSort(a[1 .. n]) {
for (i = 2; i < n; i++)
for(j = n; j >= i; j--)
if (a[j - 1] > a[j])
swap(a[j - 1], a[j]);
}

• Kích thước đầu vào:


• Thao tác cơ sở:
• Tìm công thức tính

Nhập môn lập trình 24


Ví dụ
BubbleSort(a[1 .. n]) {
for (i = 2; i < n; i++)
for(j = n; j >= i; j--)
if (a[j - 1] > a[j])
swap(a[j - 1], a[j]);
}

• Kích thước đầu vào: n


• Thao tác cơ sở: if (a[j - 1] > a[j])
• Tìm công thức tính: tổng phép so sánh được thực hiện
! (!#$)
C(n) = &
∈ O(n& )
Nhập môn lập trình 25
Mở rộng
• Phân tích độ phức tạp hàm phi đệ quy

Nhập môn lập trình 26


Bài tập
• Phân tích độ phức tạp của thuật toán tìm kiếm nhị phân
• Tính big O của thuật toán tìm kiếm nhị phân
• Phân tích độ phức tạp
int sum = 0;
for (int n = N; n > 0; n /= 2)
for (int i = 0; i < n; i++)
sum++;

Nhập môn lập trình 27

You might also like