Phương pháp chứng minh tính đúng của thuật toán và ứng dụng trong giải quyết một số bài toán tối ưu hóa

MỤC LỤC

Cấu trúc dữ liệu (Data Structure)

Sự liên hệ giữa cấu trúc dữ liệu và thuật toán rất chặt chẽ, thuật toán cần được thao tác trên các cấu trúc dữ liệu nào đó và các cấu trúc dữ liệu sẽ được xử lý bởi thuật toán nào đó. Và vì không có một cấu trúc duy nhất nào có thể tốt cho mọi mục đích hay phù hợp với mọi thuật toán do đó điều quan trọng khi nghiên cứu cấu trúc dữ liệu là cần phải biết sức mạnh cũng như giới hạn của cấu trúc dữ liệu đó để sử dụng cho phù hợp, hiệu quả.

Chương trình (Program)

Một cấu trúc dữ liệu được thiết kế cho phép thực hiện nhiều phép toán, tiết kiệm tài nguyên, ít thời gian xử lý và sử dụng không gian bộ nhớ càng ít thì càng tốt. Các cấu trúc dữ liệu được triển khai bằng cách sử dụng các kiểu dữ liệu, các tham chiếu và các phép toán trên cấu trúc dữ liệu đó được cung cấp bởi một ngôn ngữ lập trình cụ thể.

Kỹ thuật đệ quy

Có những bài toán có thể giải được bằng thuật toán nhưng cũng những bài toán chưa có thuật toán hoặc chỉ có thuật toán cho lời giải tương đối chấp nhận được. − Trong trường hợp tổng quát bài toán có thể quy về dạng tương tự với một bộ giá trị mới của tham số và sau hữu hạn lần sẽ dẫn tới trường hợp suy biến.

Phương pháp chia để trị (Divide and Conquer)

Phương pháp quay lui (Backtracking)

− Phải biểu diễn được nghiệm của bài toán dưới dạng một dãy các đối tượng như véc tơ X mà các thành phần được chọn dần từng bước từ x1, x2, .., xi,. Để đơn giản ta chỉ xét bài toán tìm các tổ hợp của tập các số nguyên đầu tiên từ 1 đến n.

Phương pháp nhánh cận

Trong quá trình mở rộng nghiệm như vậy nếu như bằng cách nào đó có thể đánh giá được tất cả các nghiệm mở rộng của nó đều không tốt bằng nghiệm tốt nhất đã biết thì ta không mở rộng nghiệm theo nhánh này nữa. Nói tóm lại, với phương pháp nhánh cận ta có thể thu hẹp phạm vi tìm kiếm nghiệm bằng cách đánh giá trong quá trình ta mở rộng các thành phần của nghiệm để bỏ đi những nhánh chắc chắn không phải là nghiệm của bài toán.

Phương pháp quy hoạch động (Dynamic Programming )

Trong thuật toán giải bài toán tối ưu thường phải giải quyết nhiều trường hợp có thể quy về các bài toán con để giải và lựa chọn giải pháp tối ưu nhất của bài toán. − Tìm công thức (gọi là công thức truy hồi) xây dựng nghiệm cho bài toán con thông qua nghiệm của bài toán con nhỏ hơn;.

Phương pháp tham lam (Greedy Method)

Ngay cả sau khi đã có thuật toán rồi thì việc phân tích thuật toán vẫn là cần thiết vì sau khi thiết xong cũng không chắc chắn hoàn toàn đó là thuật toán đúng và phù hợp với yêu cầu thực tế. Phân tích thuật toán gồm nhiều vấn đề như phân tích tính đúng, tính hiệu quả, độ phức tạp của thuật toán.

Tính đúng đắn của thuật toán

Độ phức tạp thuật toán a) Độ phức tạp về mặt thời gian

MỘT SỐ PHƯƠNG PHÁP CHỨNG MINH TÍNH ĐÚNG CỦA THUẬT TOÁN

Phương pháp quy nạp (induction) a) Phương pháp quy nạp toán học

Phương pháp bất biến vòng lặp (loop invariant). Các thuật toán không đệ quy gồm có các thành phần: các câu lệnh, biểu thức, vòng lặp. Do ta khó có thể xác định hết các trường hợp khi vòng lặp được thực hiện trong khi các thành phần còn lại của thuật toán ta có thể dễ dàng kiểm tra được tính đúng đắn của chúng. Vì thế, tính chính xác của các thuật toán này chủ yếu phụ thuộc vào các vòng lặp. Do vậy, để chứng minh thuật toán là đúng ta có thể chứng minh vòng lặp được thực hiện đúng bằng bất biến trong vòng lặp. a) Chứng minh tính đúng của thuật toán bằng phương pháp bất biến vòng lặp. Chứng minh tính đúng của thuật toán lặp bằng phương phương pháp bất biến vòng lặp có các đặc điểm như sau: Bất biến vòng lặp là biểu thức logic (của các biến được sử dụng vòng lặp) có giá trị không đổi trong quá trình lặp. Tại mỗi thời điểm của thuật toán chỉ có một vòng lặp, nếu có vòng lặp lồng nhau thì phải bắt đầu từ các vòng lặp bên trong. Sau mỗi vòng lặp bất biến vòng lặp sẽ trả lại kết quả đúng và sự đúng này phải được duy trì ở các vòng lặp tiếp theo.Sử dụng bất biến vòng lặp để chỉ ra thuật toán lặp là có tính dừng. Thông qua sự kết thúc các điều kiện chứng minh rằng thuật toán cho kết quả đúng. Như đã nói ở trên, bất biến vòng lặp là một biểu thức logic có giá trị không đổi trước mỗi vòng lặp. Từ bất biến vòng lặp, ta có thể chứng minh tính đúng của những thuật toán có chứa các vòng lặp. Tuy nhiên, không phải cứ một biểu thức nào không đổi ta cũng cho nó là bất biến vòng lặp. Sau đây ta xét một vớ dụ để làm rừ hơn nhận định này. Ví dụ: Bài toán nối chuỗi. − Những mệnh đề không đổi trước mỗi vòng lặp:. Điều này đúng, vì độ dài của bất kì một chuỗi nào cũng không âm. Điều này là hiển nhiên. Bởi vậy, nó chẳng đem lại hữu ích gì cho chúng ta trong việc chứng minh tính đúng của thuật toán. Điều này đúng. Vì trong thuật toán ta chỉ chuyển các kí tự từ chuỗi này sang chuỗi khác thôi chứ không tạo thêm mới kí tự nào. Tuy nhiên, dựa vào nhận định này ta cũng chưa thể khẳng định rằng khi kết thúc vòng lặp thì chuỗi S2 được nối vào S1. Nhận định này đúng, và hữu ích hơn nhận định trước. Vậy khi vòng lặp kết thúc ta được chuỗi S1 mà đã nối S2 vào cuối. Nhận định: S1*S2 là không đổi trước mỗi vòng lặp cho ta tính chất hữu ích giúp ta chứng minh được thuật toán đúng. Do đó, nó chính là bất biến vòng lặp cần tìm. Từ ví dụ trên ta nhận thấy, trong một vòng lặp có thể có rất nhiều những biểu thức không đổi trong quá trình lặp, nhưng không phải biểu thức nào cũng. cho ta những tính chất hữu ích để chứng minh được tính đúng của thuật toán. Vậy làm thế nào để xác định được đâu là một bất biến vòng lặp giúp ta chứng minh tính đúng của thuật toán? Sau đây là các đặc trưng của bất biến vòng lặp để phân biệt nó với những biểu thức không đổi khác trong vòng lặp. b) Các đặc trưng của bất biến vòng lặp. (vì tất cả các phần tử cho vào mảng a trước đều nhỏ hơn a[k]) vào mảng a ta được mảng con a[p.k] cũng là mảng được sắp đúng thứ tự. Đồng thời chỉ số i tăng lên một để chuyển sang phần tử nhỏ nhất trong dãy còn lại của mảng l. Ngược lại, ta làm thao tác tương tự như đối với mảng r sau đó tăng j lên một để chuyển sang phần tử nhỏ nhất trong dãy còn lại của mảng r. Như bất biến vòng lặp được duy trì đúng sau mỗi vòng lặp. Như vậy, trong mỗi mảng l và r chỉ còn lại một phần tử lính canh có giá trị vô cùng lớn +∞. Hay nói cách khác thì tất cả các phần tử không phải là lính canh đã được chép vào mảng a theo thứ tự được sắp không giảm đầy đủ t-p+1 phần tử. Như vậy thuật toán thủ tục sắp xếp trộn là đúng đắn. Tìm ước chung lớn nhất của hai số nguyên dương a,b. Thuật toán Euclid:. Để chứng minh tính đúng của thuật toán Euclid, ta cần chỉ ra rằng sau mỗi lần lặp khẳng định sau đây được giữ nguyên:. thì vòng lặp sẽ dừng, điều này là vô lý vì ta đang giả định là còn lặp nữa).

ỨNG DỤNG CHỨNG MINH TÍNH ĐÚNG CỦA MỘT SỐ THUẬT TOÁN

Bài toán: Dãy con đơn điệu tăng dài nhất

Từ phần ý tưởng trình bày, ta thấy tính đúng đắn của bài toán phụ thuộc vào việc sắp xếp lại các cặp thành phố theo thứ tự tăng dần của tọa độ các thành phố trên một bờ và phụ thuộc vào việc tìm dãy con đơn điệu tăng dài nhất của dãy tọa độ các thành phố trên bờ còn lại. Do đó, nếu ta coi như thuật toán sắp xếp (đã chứng minh ở chương 2) là đúng đắn thì tính đúng của thuật toán giải bài toán bắc cầu có thể quy về việc chứng minh tính đúng của thuật toán quy hoạch động tìm dãy con đơn điệu tăng dài nhất của một dãy số (tọa độ của các thành phố trên một bờ).

Bài toán: Chia kẹo

Độ lệch d là nhỏ nhất vì K là giá trị lớn nhất của tổng dãy con có thể thu được từ dãy ban đầu a[.]. Ta có thể giảm không gian lưu trữ bằng cách sử dụng mảng 1 chiều để lưu kết quả vì để tính dòng thứ i ta chỉ cần tính thông qua dòng thứ i-1.

Bài toán Cây bao trùm nhỏ nhất (Minimum spanning tree)

Giả sử v là đỉnh vừa được kết nạp thêm vào, khi đó theo thuật toán đỉnh v có nhãn là chính là trọng số nhỏ nhất từ đỉnh v ngoài cây T tới một đỉnh u thuộc cây T do đó đảm bảo bất biến là cây T nằm trong cây bao trùm nhỏ nhất. Vì vây, bài toán đặt ra dẫn về bài toán tìm cây khung nhỏ nhất trên đồ thị đầy đủ n đỉnh, mỗi đỉnh tương ứng với một thành phố, với độ dài trên các các cạnh chính là chi phí xây dựng đường ray nối hai thành phố tương ứng.