Professional Documents
Culture Documents
Example: Kiểm tra các phần tử trong mảng có phải là duy nhất không
Kích thước đầu vào là n, số phần tử trong mảng. Chúng ta coi phép so sánh trong vòng lặp là phép
toán cơ bản của thuật toán. Tuy nhiên, lưu ý rằng số lượng phần tử được so sánh không chỉ phụ thuộc vào
n mà còn phụ thuộc vào việc có các phần tử bằng nhau trong mảng hay không và nếu có thì chúng chiếm
vị trí mảng nào. Chúng ta sẽ xem xét trong trường hợp xấu nhất.
Có hai loại đầu vào trong trường hợp xấu nhất: phần tử trong mảng không bằng nhau và 2 phần tử
cuối cùng là cặp phần tử bằng nhau duy nhất. Vòng lặp bên trong mỗi giá trị của biến vòng lặp j, giới hạn
của nó i + 1 và n – 1. Vòng lặp bên ngoài, giá trị của biến vòng lặp i có giới hạn 0 và n − 2 của nó. Theo
đó, chúng ta nhận được
Example: Tìm số chữ số nhị phân trong biểu diễn nhị phân của một số nguyên dương.
Thao tác được thực hiện thường xuyên nhất là phép so sánh (n>1) chứ không phải các thao tác trong vòng
lặp. Số lần so sánh (n>1) sẽ được thực hiện lớn hơn số lần lặp lại phần thân của vòng lặp đúng 1. Vì giá trị
của n giảm đi một nửa sau mỗi lần lặp lại vòng lặp nên câu trả lời sẽ là log2 n. Công thức chính xác cho số
lần phép so sánh n > 1 sẽ được thực hiện thực ra là log2 n + 1—số bit trong biểu diễn nhị phân của n theo
công thức.
2.4 Phân tích toán học của thuật toán đệ quy
Các tiêu chí chung để phân tích hiệu quả thời gian của các thuật toán đệ quy
- Xem xét biết kích thước của đầu vào.
- Xác định thao tác cơ bản của thuật toán.
- Kiểm tra xem số lần thao tác cơ bản được thực thi có thể thay đổi trên các đầu vào khác nhau có
cùng kích thước hay không; nếu có thể, hiệu quả trong trường hợp xấu nhất, trường hợp trung bình
và trường hợp tốt nhất phải được điều tra riêng biệt.
- Thiết lập một quan hệ truy hồi, với điều kiện ban đầu thích hợp, cho số lần phép toán cơ bản được
thực hiện.
- Giải quyết sự lặp lại hoặc, ít nhất, xác định thứ tự phát triển của giải pháp của nó.
Example: Câu đố tháp Hà Nội: Ban đầu, tất cả các đĩa nằm trên chốt đầu tiên theo thứ tự kích thước, lớn
nhất ở dưới cùng và nhỏ nhất ở trên cùng. Mục tiêu là di chuyển tất cả các đĩa sang chốt thứ ba, sử dụng
chốt thứ hai làm phụ trợ, nếu cần. Chúng ta chỉ có thể di chuyển một đĩa tại một thời điểm và không được
phép đặt đĩa lớn hơn lên trên đĩa nhỏ hơn.
Bài toán có một lời giải đệ quy đơn giản, được minh họa trong
Số lượng đĩa n là kích thước của đầu vào, di chuyển một đĩa như hoạt động cơ bản của thuật toán. số lần
di chuyển M(n) chỉ phụ thuộc vào n và chúng ta có phương trình truy hồi sau cho nó:
Với điều kiện ban đầu rõ ràng M(1) = 1, ta có phép truy hồi sau quan hệ cho số lần di chuyển M(n):
Có thể giải quyết sự lặp lại này bằng cùng một phương pháp thay thế ngược:
Vì điều kiện ban đầu được chỉ định cho n = 1, điều này đạt được cho i = n - 1, nên chúng ta
nhận được công thức sau đây cho giải pháp truy hồi (2.3):
Chúng ta có một thuật toán hàm mũ, thuật toán này sẽ chạy trong một thời gian dài không thể tưởng tượng
được ngay cả đối với các giá trị vừa phải của n. Không phải do thuật toán này kém, không khó để chứng
minh thuật toán này hiệu quả. Chính độ khó nội tại của vấn đề khiến nó trở nên khó tính toán. Tuy nhiên,
ví dụ này đưa ra một điểm chung quan trọng:
Người ta nên cẩn thận với các thuật toán đệ quy vì tính ngắn gọn của chúng có thể che giấu sự kém
hiệu quả của chúng.
2.5 Ví dụ: Tính số Fibonacci thứ n
Thuật toán đệ quy tính đệ quy số Fibonacci thứ n bằng cách sử dụng định nghĩa của nó
Số phép cộng cần thiết để tính F (n - 1) và F (n - 2) lần lượt là A(n - 1) và A(n - 2) và thuật toán cần thêm
một phép cộng nữa để tính tổng của chúng. Do đó, chúng tôi nhận được sự truy hồi sau cho A(n):
Chúng ta có thể giảm sự truy hồi không đồng nhất của mình thành một sự đồng nhất bằng cách viết lại nó
dưới dạng:
Loại hiệu quả kém của thuật toán có thể được dự đoán bởi bản chất của sự lặp lại. Nó chứa hai lệnh gọi đệ
quy với kích thước của các trường hợp nhỏ hơn chỉ nhỏ hơn một chút so với kích thước n.
Chúng ta có một thuật toán nhanh hơn nhiều bằng cách đơn giản tính toán lặp đi lặp lại các phần tử liên
tiếp của dãy Fibonacci:
Thuật toán này rõ ràng tạo ra n − 1 phép cộng. Do đó, nó là tuyến tính dưới dạng hàm của n và hàm mũ
“chỉ” là hàm của số bit b trong biểu diễn nhị phân của n.
Cuối cùng, tồn tại một thuật toán (log n) để tính toán số Fibonacci thứ n chỉ thao tác với các số nguyên.
Nó dựa trên sự bình đẳng