Nội dung chương này gồm các chiến lược chứng minh tính đúng của thuật toán; các phương pháp cụ thể để chứng... minh tính đúng của thuật toán như phương pháp quy nạp và phương pháp bất bi
Trang 1ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN
-
Bế Thị Hương
MỘT SỐ PHƯƠNG PHÁP CHỨNG MINH TÍNH ĐÚNG CỦA THUẬT TOÁN VÀ ỨNG DỤNG
LUẬN VĂN THẠC SĨ KHOA HỌC
Hà Nội – Năm 2015
Trang 2ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN
-
Bế Thị Hương
MỘT SỐ PHƯƠNG PHÁP CHỨNG MINH TÍNH ĐÚNG CỦA THUẬT TOÁN VÀ ỨNG DỤNG
Chuyên ngành: Cơ sở Toán học cho Tin học
Mã số: 60460110
LUẬN VĂN THẠC SĨ KHOA HỌC
NGƯỜI HƯỚNG DẪN KHOA HỌC: TS NGUYỄN THỊ HỒNG MINH
Hà Nội – Năm 2015
Trang 3MỞ ĐẦU
Để đánh giá một thuật toán là tốt có rất nhiều tiêu chí trong đó không thể bỏ qua tính đúng của thuật toán Và đây cũng là nội dung chính của luận văn này theo đề tài nghiên cứu: “Một số phương pháp chứng minh tính đúng của thuật toán và ứng dụng” Luận văn nhằm tìm hiểu, nghiên cứu, tổng hợp phương pháp chứng minh tính đúng của thuật toán Cấu trúc luận văn gồm 3 chương, nội dung chính như sau:
Chương 1 Tổng quan về phân tích thuật toán
Chương này nhằm tổng hợp lại một số kiến thức chung về bài toán, thuật toán, cấu trúc dữ liệu, chương trình
và kiến thức về phân tích thuật toán Trong chương này còn tổng hợp lại một số phương pháp thiết kế thuật toán thường
sử dụng trong thực tế Như kỹ thuật đệ quy, phương pháp chia để trị, phương pháp quay lui, phương pháp nhánh cận, phương pháp quy hoạch động và phương pháp tham lam
Chương 2 Một số phương pháp chứng minh tính đúng của thuật toán
Nội dung chương này gồm các chiến lược chứng minh tính đúng của thuật toán; các phương pháp cụ thể để chứng
Trang 4minh tính đúng của thuật toán như phương pháp quy nạp và phương pháp bất biến vòng lặp
Trong đó, phương pháp quy nạp chứng minh cho các thuật toán đệ quy, phương pháp bất biến vòng lặp chứng minh cho các thuật toán không đệ quy Đối với mỗi phương pháp trình bày về đặc điểm, phương pháp chung đồng thời nêu một số ví dụ về thuật toán và chứng minh tính đúng của các thuật toán đó
Chương 3 Ứng dụng chứng minh tính đúng của một
Trang 5CHƯƠNG 1 TỔNG QUAN VỀ PHÂN TÍCH THUẬT
TOÁN
Để khẳng định được một thuật toán là tốt là một điều không dễ dàng gì Thật vậy, để đánh giá một thuật toán tốt ta cần rất nhiều kỹ thuật từ thiết kế, phân tích đến đánh giá một thuật toán Ở chương này đề cập tổng quát đến các vấn đề trong phân tích thuật toán và một số thuật toán cơ bản thường dùng trong khoa học tính toán hiện đại
1.1 Một số khái niệm cơ bản
1.1.1 Bài toán
Điểm quan trọng đầu tiên khi giải một bài toán trên máy tính đó là cần xác định rõ những gì đã biết input (dữ liệu vào) và kết quả cần thu được output (dữ liệu ra) và phân tích mối quan hệ giữa hai yếu tố đó
1.1.2 Thuật toán (Algorithm)
Để giải một bài toán trên máy tính sau khi đã xác định
rõ ràng về bài toán việc quan trọng nhất là phải đưa ra một thuật toán tốt, thuật toán này có thể là một thiết kế mới hoặc
Trang 6lựa chọn một thuật toán đã có Thuật toán là để biểu diễn về cách giải một bài toán trên máy tính
Định nghĩa: Thuật toán (Algorithm) để giải một bài
toán là một dãy hữu hạn các thao tác được sắp xếp theo một trình tự xác định, sao cho sau khi thực hiện dãy thao tác ấy,
từ dữ liệu vào có thể là một giá trị hoặc một tập giá trị (input) của bài toán ta nhận được một giá trị hoặc một tập giá trị còn gọi là dữ liệu ra (output) của bài toán đó
1.1.3 Cấu trúc dữ liệu (Data Structure)
1.1.4 Chương trình (Program)
Chương trình = Thuật toán + Cấu trúc dữ liệu Chương trình là sự thể hiện bằng một ngôn ngữ lập trình cụ thể một thuật toán đã cho được thể hiện trên một cấu trúc dữ liệu xác định Việc lựa chọn cấu trúc dữ liệu phù hợp với thuật toán hoặc ngược lại lựa chọn thuật toán phù hợp với cấu trúc dữ liệu cụ thể còn phụ thuộc vào mục đích của chương trình, kỹ năng người lập trình và khả năng của ngôn ngữ lập trình cụ thể
Trang 71.2 Một số phương pháp thiết kế thuật toán
Ngày nay có nhiều phương pháp thiết kế thuật toán đã được nghiên cứu và sử dụng trong công nghệ phần mềm 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 luận văn này nghiên cứu về các phương pháp thiết kế thuật toán và ứng dụng cho các bài toán có thuật toán để giải
1.2.1 Kỹ thuật đệ quy
Đệ quy là một khái niệm cơ bản trong toán học và tin học Ta nói một đối tượng là đệ quy nếu nó được định nghĩa qua chính nó hoặc một đối tượng cùng dạng với chính nó bằng quy nạp Ý tưởng của kỹ thuật đệ quy đó là chia bài toán cần giải quyết thành nhiều bài toán nhỏ hơn, việc chia này thực hiện cho đến khi bài toán con có lời giải và lời giải này thường là tường minh và tương đối đơn giản
Khái niệm giải thuật đệ quy: Một bài toán T được
thực hiện bằng giải thuật của một bài toán T’ có dạng giống như T thì giải thuật đó gọi là giải thuật đệ quy
Trang 8Bài toán T’ tuy có dạng giống bài toán T nhưng T’ theo một nghĩa nào đó phải là bài toán nhỏ hơn T Bài toán T’ phải dễ giải hơn bài toán T và việc giải bài toán T’ không cần dùng đến T
1.2.2 Phương pháp chia để trị (Divide and Conquer)
Phương pháp chia để trị có tư tưởng là chia bài toán ban đầu thành các bài toán con tương tự Các bài toán con tiếp tục được chia nhỏ hơn, cứ chia liên tiếp như vậy cho tới khi gặp bài toán con đã có lời giải hoặc có thể dễ dàng đưa ra lời giải Sau đó lần lượt giải các bài toán con này và kết hợp các kết quả lại với nhau ta thu được kết quả cần tìm của bài toán ban đầu
1.2.3 Phương pháp quay lui (Backtracking)
Tư tưởng của thuật toán quay lui đó là tìm nghiệm của bài toán bằng cách xem xét tất cả các phương án có thể Ta
có thể thử duyệt các phương án cho đến khi tìm thấy phương
án đúng còn gọi là phương pháp thử sai Với tốc độ xử lí nhanh của máy vi tính thì phương pháp này có thể giải quyết được nhiều bài toán tuy nhiên nếu kích thước bài toán quá lớn thì nó trở nên không phù hợp Bởi vì nếu kích thước bài
Trang 9toán lớn thì kéo theo thời gian duyệt các phương án và độ phức tạp về mặt không gian cũng lớn và có thể lớn đến mức nào đó không thể chấp nhận được Do đó phương pháp này thường chỉ hữu dụng với các bài toán có kích thước nhỏ
1.2.4 Phương pháp nhánh cận
Tư tưởng của phương pháp nhánh cận như sau: Ta
xây dựng dần dần các thành phần của nghiệm Giả sử ta đã xây dựng được k thành phần của véc tơ nghiệm
(x , x , , x1 2 k), nhiệm vụ tiếp theo là phải xây dựng được
thành phần thứ k+1 tức là tìm xk+1 cho phù hợp 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ó
(x , x , , x , x , 1 2 k k+1 ) đề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 Như vậy thuật toán nhánh cận sẽ nhanh hơn thuật toán quay lui vét cạn vì nhánh cận không phải duyệt hết tất cả các trường hợp của bài toán 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à
Trang 10nghiệm của bài toán Do đó phương pháp nhánh cận sẽ nhanh hơn và bớt độ phức tạp về mặt không gian
1.2.5 Phương pháp quy hoạch động (Dynamic
Programming )
Phương pháp quy hoạch động nhìn chung được áp dụng cho lớp các bài toán tối ưu và cho kết quả đúng 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
Các bước để giải bài toán bằng quy hoạch động gồm những công việc chính sau đây:
− Tìm nghiệm của bài toán con nhỏ nhất (Thường là trường hợp suy biế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;
− Tạo bảng phương án lưu trữ giá trị nghiệm của các bài toán con;
− Từ bảng phương án suy ra nghiệm của bài toán ban đầu cần giải
Trang 111.2.6 Phương pháp tham lam (Greedy Method)
Tư tưởng của phương pháp tham lam như sau: Ta
xây dựng dần dần các thành phần của nghiệm Giả sử ta đã xây dựng được k thành phần của véc tơ nghiệm
(x , x , , x1 2 k), nhiệm vụ tiếp theo là phải xây dựng được
1.3 Phân tích thuật toán
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
Trang 121.3.1 Tính đúng đắn của thuật toán
Thiết kế xong một thuật toán câu hỏi luôn luôn phải
có đó là thuật toán được thiết kế đã đúng chưa? Cách đơn giản nhất mà được sử dụng thông dụng đó là viết chương trình cho thuật toán đã thiết kế và chạy thử chương trình với nhiều bộ dữ liệu vào cụ thể (tests) để kiểm tra dữ liệu ra có chuẩn xác hay chưa Tuy nhiên, cách này cũng chỉ khẳng định được thuật toán đúng với các trường hợp cụ thể mà thôi
Có một cách khác chứng minh được thuật toán đúng đó là chứng minh bằng toán học Nhưng với cách chứng minh thuật toán đúng bằng toán học thì phức tạp hơn nhiều và đòi hỏi nhiều kiến thức tổng hợp cả về toán học và tin học cộng với khả năng của người thực hiện việc chứng minh thuật toán Chúng ta sẽ nghiên cứu việc này cụ thể hơn ở các chương sau
1.3.2 Độ phức tạp thuật toán
a) Độ phức tạp về mặt thời gian
b) Độ phức tạp về mặt không gian
Trang 13CHƯƠNG 2 MỘT SỐ PHƯƠNG PHÁP CHỨNG MINH
TÍNH ĐÚNG CỦA THUẬT TOÁN
Chúng ta đã biết thuật toán là vô cùng quan trọng và
có thể nói là thuật toán mang tính chất quyết định để giải một bài toán trên máy tính Nhưng một thuật toán vừa thiết kế xong chưa thể khẳng định được ngay là thuật toán đó có đúng hay không Ở chương này nghiên cứu tổng quan về các chiến lược chứng minh tính đúng của thuật toán Nghiên cứu chi tiết về chiến lược chứng minh tính đúng của thuật toán một cách trực tiếp dựa vào toán học mà không cần chạy các
bộ test chương trình cụ thể
2.1 Các chiến lược chứng minh tính đúng thuật toán
Để kiểm tra thuật toán có đúng hay không ta có nhiều chiến lược như kiểm thử, chứng minh tính đúng hoặc kết hợp
cả kiểm thử và chứng minh tính đúng nhưng mỗi chiến lược đều có ưu, nhược điểm riêng Sau đây là một số đặc điểm sơ lược về mỗi chiến lược
a) Kiểm thử (Testing):
b) Chứng minh tính đúng (Correctness proof):
Trang 14Với chiến lược chứng minh tính đúng của thuật toán cần dùng các kiến thức toán học để chứng minh thuật toán đúng Cách này chứng minh được cho bài toán tổng quát nhưng đòi hỏi tư duy trừu tượng và logic toán học chặt chẽ
Có các phương pháp chứng minh tính đúng của thuật toán như phương pháp quy nạp, phương pháp bất biến vòng lặp Đây cũng là nội dung nghiên cứu chủ yếu khi thực hiện luận văn này
c) Kết hợp kiểm thử và chứng minh tính đúng:
Để đảm bảo tính đúng của thuật toán một cách chặt chẽ hơn nữa ta có thể kết hợp cả hai chiến lược kiểm thử và chứng minh tính đúng đã nêu ở trên
2.2 Các phương pháp chứng minh tính đúng (Correctness proofs)
Làm thế nào để biết thuật toán hoạt động thế nào? Cách tốt nhất là chứng minh thuật toán là đúng Có một số phương pháp chứng minh tính đúng của thuật toán như: Đối với các thuật toán đệ quy có thể chứng minh tính đúng bằng phương pháp quy nạp Đối với các thuật toán không đệ quy
Trang 15có thể sử dụng phương pháp bất biến vòng lặp cho mọi vòng lặp
2.2.1 Phương pháp quy nạp (induction)
a) Phương pháp quy nạp toán học
b) Chứng minh tính đúng của thuật toán bằng phương pháp quy nạp
Các thuật toán nếu chỉ có các dòng lệnh đơn lẻ không
có chứa đệ quy hay lặp thì ta dễ dàng thấy được tính đúng của nó nhưng với các thuật toán có chứa đệ quy hay vòng lặp thì việc chứng minh trở nên phức tạp hơn Sau đây ta sử dụng phương pháp quy nạp toán học đã nêu ở trên để chứng minh tính đúng của thuật toán đệ quy
Ta sẽ chứng minh tính đúng của thuật toán đệ quy bằng phương pháp quy nạp theo kích thước dữ liệu vào như sau:
− Cơ sở của quy nạp: Trường hợp suy biến của đệ quy Đây cũng chính là điều kiện phải có để thuật toán có tính dừng
Trang 16− Giả thiết quy nạp: Giả sử thuật toán đúng với dữ liệu kích thước n
− Tổng quát: Chứng minh thuật toán đúng với dữ liệu kích thước n+1
c) Một số ví dụ
2.2.2 Phương pháp bất biến vòng lặp (loop invariant) 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
Trang 17b) Các đặc trưng của bất biến vòng lặp
− Khởi tạo: bất biến của vòng lặp phải đúng trước lần lặp đầu tiên
− Duy trì: Nếu bất biến vòng lặp đúng trước một vòng lặp thì bất biến vòng lặp vẫn còn đúng trước vòng lặp tiếp theo
− Kết thúc: Khi vòng lặp kết thúc, bất biến vòng lặp này cho chúng ta một tính chất hữu ích giúp chứng minh được thuật toán là đúng đắn
c) Một số ví dụ
Trang 18CHƯƠNG 3 ỨNG DỤNG CHỨNG MINH TÍNH
ĐÚNG CỦA MỘT SỐ THUẬT TOÁN
Việc chứng minh tính đúng của thuật toán bằng toán học đòi hỏi nhiều kiến thức tổng hợp Ở chương này nhằm nghiên cứu và chứng minh một số thuật toán kinh điển cùng với ứng dụng của nó trong việc giải quyết các bài toán trong thực tế Mặc dù các thuật toán kinh điển đã ra đời từ lâu nhưng nó vẫn luôn được cải tiến và đưa vào sử dụng trong nhiều phần mềm hiện nay Vì để tìm được một bất biến vòng lặp đúng để chứng minh thuật toán đúng là vấn đề khó nên sau đây nghiên cứu về các bài toán và thuật toán sử dụng phương pháp bất biến vòng lặp:
3.1 Bài toán: Dãy con đơn điệu tăng dài nhất
Cho một dãy gồm n số nguyên a1, a2, , an Tìm dãy con đơn điệu tăng có độ dài lớn nhất của dãy số đó (các phần
tử có thể không liền kề nhau nhưng phải giữ nguyên thứ tự ban đầu)
Nhận xét: Tất cả các dãy con của dãy số n phần tử ban đầu là 2n Do đó phương pháp duyệt tất cả các dãy con và lựa chọn dãy phù hợp là không thể thực hiện khi n lớn vì không gian duyệt là quá lớn Do đó ta lựa chọn phương pháp quy
Trang 19hoạch động nhằm tiết kiệm không gian nhớ và ít chi phí thời gian hơn để giải bài toán đã cho
3.2 Bài toán: Chia kẹo
Có n gói kẹo, gói kẹo thứ i chứa a[i] chiếc kẹo, đưa ra cách chia các gói kẹo thành 2 phần sao cho độ lệch về số kẹo trong hai phần là ít nhất
− Input: Dữ liệu vào từ tệp ChiaKeo.INP
+ Dòng đầu là số gói kẹo n
+ Dòng thứ hai là số cái kẹo trong từng gói
− Output: Dữ liệu ra tệp ChiaKeo.OUT
+ Số gói kẹo trong mỗi phần sau khi được chia
3.3 Bài toán Cây bao trùm nhỏ nhất (Minimum spanning tree)
Bài toán: Cho đồ thị vô hướng có trọng số
G=(V,E,w) Gọi T là cây bao trùm của G, w(T) là trọng số của cây bao trùm T Trọng số của cây bao trùm T là tổng trọng số các cạnh trong T Trong một đồ thị có thể có nhiều cây bao trùm, vấn đề đặt ra là cần tìm cây bao trùm có trọng
số nhỏ nhất hay còn gọi là cây bao trùm nhỏ nhất
− Input: Đồ thị vô hướng có trọng số G=(V,E,w)