Hoàng Quang, người thầy đã hướng dẫn tận tình và có những góp ý sâu sắc, hướng dẫn rất quý báu cho tôi trong suốt quá trình nghiên cứu, kịp thời cho tôi nhiều lời động viên cũng như nhữn
Trang 1BỘ GIÁO DỤC VÀ ĐÀO TẠO DAI HOC HUE
TRUONG DAI HOC KHOA HOC
LE THI LAN
UNG DUNG KY THUAT DE QUY NHANH CAN TRONG BOI DUONG HOC SINH GIOI
TIN HOC TRUNG HOC PHO THONG
LUAN VAN THAC SI KHOA HOC
CONG NGHE THONG TIN
Thira Thién Hué, 2020
Trang 2
LỜI CAM ĐOAN
Tôi xin cam đoan đây là công trình nghiên cứu của riêng cá nhân tôi, dưới sự hướng dẫn khoa học của PGS.TS Hoàng Quang
Các kết quả nêu trong luận văn là trung thực và chưa từng được công bố trong bat kỳ công trình khoa học nào khác
Thừa Thiên Huế, ngày 4 tháng 02 năm 2020 Học viên
Trang 3LỜI CẢM ƠN
Lời đầu tiên, tôi xin gởi lời cảm ơn chân thành sâu sắc đến Quý thầy cô giáo Khoa
Công nghệ thông tin - Trường Đại học Khoa học Huế đã tận tình hướng dẫn, truyền đạt kiến thức, tạo điều kiện thuận lợi trong quá trình học tập và thực hiện luận văn tốt nghiệp
Tôi xin chân thành gửi lời biết ơn đến PGS.TS Hoàng Quang, người thầy đã hướng dẫn tận tình và có những góp ý sâu sắc, hướng dẫn rất quý báu cho tôi trong suốt quá trình nghiên cứu, kịp thời cho tôi nhiều lời động viên cũng như những nhận xét đúng
đắn để tôi có thê hoàn thành tốt được đề tài này
Trong quá trình thực hiện đề tài, xin chân thành gửi lời cảm ơn đến sự giúp đỡ, những lời động viên từ phía gia đình, đồng nghiệp, bạn bè là động lực to lớn giúp tôi hoàn thành tốt đề tài nghiên cứu của mình Tôi cũng gửi lời cảm ơn đến trường THPT
Hoàng Hoa Thám, nơi tôi đang công tác đã tạo điều kiện đi học và thực hiện đề tài
nghiên cứu này
Bản thân tôi đã cố gắng hết sức trong quá trình thực hiện để tài này nhưng chắc chắn sẽ không tránh khỏi những thiếu sót Kính mong quý thầy cô và các bạn tận tình góp ý, chỉ bảo
Xin chan thành cám on!
Thừa Thiên Huế, ngày 4 tháng 02 năm 2020 Học viên
Trang 4MỤC LỤC Trang LỜI CAM ĐOAN cá HH HH HH HH HH gu ghe i U89) 0 ii I/180/9005 92 518. ‹ .Ả 1H DANH MỤC CÁC HÌNH 22- 2S 2222212212112112112112112112211222 ra M DANH MỤC CÁC TỪ VIẾT TẮT 2-222222222212221222122112112212222 ae Vv 90 1000Ẻ® 1 1 Tính cấp thiết của để tài 22 52 222211211121121121121211222222222re 1 Vi 0130 i09 8 2 3 Đối tượng và phạm vi nghiên cứu ©2222222212211221121112111111211211222 xe 2 4; Phương pháp nghiÊn 'CỨU:sex s22 tUtUSGEEEEIGSIESIRDAISEIEDIEEIVREEIVEEHEEESRRNGSSEPASESSR 2
5 Bố cục của để tài -S s n 21 1112111121111 2111211112111 22111211 reo 3
6 Tổng quan tài liệu tham khảo ©22-©2222222512251223122112111221121112111211211 2122 xe 4
Chương 1 GIỚI THIỆU VẺ PHƯƠNG PHÁP LẬP TRÌNH ĐẸ QUY 5 1.1 Giới thiệu về đệ quy -©2222222221211121112111211111111112112112212e 5
1.2 Các bước để giải bài toán bằng phương pháp đệ quy - 22 2sc22zz22sce2 8 1,3, Gidithiéu:phuong: phép vel Can secnccumesenseescemmnceeueneeemeenmrennr ee emees 12 1.4 Giải một số bài toan bang cach sir dung dé quy quay Wi eee 14 1.4.1 Bài toán liệt kê các dãy nht phan ee ceceeeeeeeeereeeeneeteeseneeneeneeeeneens 15
1.4.2 Bài toán liệt kê các hoán vị của tập các số nguyên 1,2, N 17
1.5 Tiểu kết chương Ì -252 222 2212221221222122112211221121121222222 re 18
Chương 2 KỸ THUẬT ĐỆ QUY NHÁNH CẬN 2- 25522222 c2sccrcrrree 19
2.1 Bài toán tối ưu tổ hợp - 22-221 221222121121121121121122112112222222 ae 19
2.2 Cách giải một số bài toán bằng phương pháp đệ quy nhánh cận 20
Trang 52.2.1 Bài toán người du lịch S21 t1 1x này HH He te ere 23 2.2.2 Bài toán máy rút tiền tự động ATM -22222222212221222221.2 e6 26 2.3 So sánh giữa phương pháp đệ quy nhánh cận với phương pháp quy hoạch động 28 2.3.1 Bài toán cái túi xách (không bị chặn) óc St xen nrrerrerre 31 2.3.2 Bai toan cai thi (b1 chan) (Knapsack Problem) «0.0.0.0 cece 38
2.4 Tiểu kết chương 2 222222 221122121122121122112112211221122112222222 re 4 Chương 3 ÁP DỤNG PHƯƠNG PHÁP ĐẸ QUY NHANH CAN DE GIAI CAC BÀI TOÁN HỌC SINH GIỎI ©52 22222522252211122112111221121112112212222 xe 42
3.1 Bài toán tối ưu -22c 2221 22112221 221112211 1112111211211 212 ree 42 3.1.1 Bài tốn chấm điểm (V§SCORE spoj) 52-222 222222122122222.2 xe 43
3.1.2 Bài toán người nông dân Farmer (IOI 2004) - ¿5c cccsxcccsvrsxssxeee 45 3.1.3 Bài toán Xây cung điện (Nguồn Olympie miền Nam-20 l 1) 47 3.1.4 Bài toán dãy ABC - 00 220 2211 2221221122211211121121112121 21a 48 3.1.5 Bài tốn Robof qT VƠI t2 211212 E1 tt Hy Hà Hà tre 49
3.2 Bài toán đỗ thị con đầy AU CUC 0 ằ.ằằ 51
3.2.1 Phát biểu bai toa o.oo ccc ccceecssesessssessssesssesssiessssssiesssieesssesssessitessiesseees 51 3.2.2 Thu dt toa oc ccccccccseccsssssssssessssesssssiisessssessisssisssisssiisssseessesssesseseeeseees 53
3.3 Tiểu kết chương 3 2 222 2212221222122122122112222122222222 22a 55 KET LUẬN . - 2-2222 2212212211221221211212122222222re 56
Trang 6người 7 ( < ?) Mảng đeg[1 m] và eou[1 n] được sử dụng trong hàm cận để hạn chế bớt không gian duyệt
+ Hàm cận:
Thuật toán nhánh cận được thực hiện thông qua thử tục 41/mp/@): Thử hai
giá trị có thể gán cho x¡ Thuật toán được bắt đầu bằng thủ tục 4#emp£(L) và khi thủ tục /empf() được gọi thì ta đang có một phương án chọn trên tập những người từ l tới ¡- I và số người đang được chọn trong tập này là #
Trong những người từ ¿ tới N, chắc chắn nếu có chọn thêm thì ta chỉ được phép chọn những người j mà cøz[7] > k và deg[j] > &besr Điều này ta có thể dễ nhìn thấy duoc: count{j] < k có nghĩa là người 7 không quen với ít nhất một người đã chọn; còn đeg[7] < &besf có nghĩa là nếu người 7 được chọn, phương án tìm được chắc chắn không thể có nhiều hơn &ưes/ người, khơng tốt hơn phương án öes hiện có
* Duyệt kiểm tra xem n gười thứ 1 có được chọn trong lần xét hiện tại hay không,
ta xây dựng thủ tục sau:
Procedure Attempt(: Integer); Var j: Integer;
Begin
// Kiém tra xem cé bao nhiéu ngwoi doc chon th ngwéi i dén ngwoi thứ n / Nếu số người nhỏ hơn kết qua tốt nhất thì không xét tiếp nữa
1 UpperBound() <= kbest then Exit;
Trang 7MỞ ĐẦU
1 TÍNH CÁP THIẾT CỦA ĐÈ TÀI
Ngày nay nhắc đến ngành Công nghệ thông tin là một ngành đào tạo đại học “hot” nhất trên các trang mạng Tại các trường Trung học phổ thông (THPT) khi đăng ký thi đại học thì tỷ lệ học sinh đăng ký vào các ngành Công nghệ thông tin cũng rất nhiều Nhưng trong các trường THPT thì môn Tin học lại là một môn phụ vì không
thi tốt nghiệp Nhiệm vụ quan trọng trong đào tạo THPT là đào tạo một cách toàn
diện đồng thời chú trọng bồi dưỡng phát triển năng lực của học sinh Chính vì vậy một trong những tiêu chí đánh giá chất lượng giáo dục của trường THPT là kết quả
của việc thực hiện hoạt động bồi dưỡng học sinh giỏi
Đối với giáo viên bộ môn Tin học, bồi dưỡng học sinh giỏi THPT đòi hỏi giáo
viên phải hiểu biết về lập trình và cần có các phương pháp giảng dạy thuật toán tốt giúp hoc sinh dé dang tiếp thu và vận dụng Học sinh muốn đạt kết quả cao trong kỳ thi học sinh giỏi tỉnh và cao hơn, cần phải có lượng kiến thức lớn và sâu trong việc lập trình Những kiến thức này đối với chương trình phổ thông bình thường là không đủ đáp ứng Nhiệm vụ của giáo viên là cung cấp thêm cho các em kiến thức, phương pháp lập trình đề học sinh đạt kết quả tốt trong kỳ thi
Việc bồi dưỡng học sinh giỏi Tĩn là một vấn để rất khó khăn, vì môn Tin hoc
không thi tốt nghiệp THPT nên các em rất ít đầu tư vào môn này, chỉ có một số em
yêu thích môn học này thì mới đầu tư vào Nhưng khi vận động được các em vào đội tuyển học sinh giỏi thì một vấn để nan giải đặt ra là học được một thời gian các em
cảm thấy môn này rất khó vì thứ nhất cần kiến thức Toán học, và cần cả kiến thức về lập trình, nhiều em nản và bỏ cuộc giữa chừng Vì vậy để duy trì được đội tuyển Tin học rất khó khăn Do đó chúng ta nên đưa ra những bài toán có ứng dụng và chuyển tải nội dung cho các em từ dễ đến khó, từ những kiến thức thường ngày đề có thé di dần vào lập trình
Trang 8hơn Biết được mối quan hệ giữa đệ quy và các phương pháp khác sẽ giúp việc giải các bài toán đễ dàng và nhanh chóng hơn
2 MỤC TIỂU NGHIÊN CỨU
Là một giáo viên giảng dạy bộ môn Tìn học ở trường THPT, việc bồi dưỡng học
sinh giỏi là nhiệm vụ vô cùng quan trọng, tôi nhận thấy việc ứng dụng phương pháp đệ quy trong thiết kế thuật toán là một mảng kiến thức rất cần thiết đối với học sinh tham gia bồi dưỡng học sinh giỏi
Đề tài “Ứng dụng kỹ thuật đệ quy nhánh cận trong bồi dưỡng học sinh giỏi Tin học Trung học phổ thông” được thực hiện nhằm nâng cao chất lượng và hiệu qua dao tao Tao điều kiện tốt nhất cho học sinh giành được các giải cao trong các kỳ thi học sinh giỏi môn tin học cấp tỉnh, cấp quốc gia và hướng đến có giải trong kỳ thi olympic tin học quốc tế
Đổi mới phương pháp đạy và học trong bồi dưỡng học sinh giỏi ở trường THPT, từ đó, giáo viên và học sinh nắm được phương pháp nhánh cận thông qua việc khảo
sát một số bài toán cụ thể, tiêu biểu Học được cách nghĩ, cách tiếp cận vấn đề, cách
thiết kế giải thuật và rèn luyện kỹ năng linh hoạt khi giải các bài toán Vận dụng được
thuật toán nhánh cận vào giải một số bài toán cụ thể để giáo viên và học sinh tiếp cận
với phương pháp nhánh cận một cách nhanh chóng và hiệu quả Nắm bắt được một
số kỹ thuật quan trọng trong việc tiếp cận bài toán, tìm và thiết kế thuật toán
3 ĐÓI TƯỢNG VÀ PHẠM VI NGHIÊN CỨU
Tìm hiểu phương pháp đệ quy nhánh cận, trên cơ sở đó tiến hành phân tích và thiết kế thuật toán và cài đặt các bài toán tiêu biêu có thê giải được bằng phương pháp nhánh cận Các bài toán được cài đặt chương trình bằng ngôn ngữ lập trình Pascal để
minh họa quá trình thực hiện thuật toán
4 PHƯƠNG PHÁP NGHIÊN CỨU
Bài toán đặt ra trong thực tế yêu cầu tìm ra một nghiệm thỏa mãn một số điều kiện nào đó và nghiệm đó là tốt nhất theo một chỉ tiêu cụ thể, đó là lớp bài toán tối
ưu Nghiên cứu lời giải các lớp bài toán tối ưu thuộc về lĩnh vực quy hoạch toán học
Trang 9Tuy nhiên cũng cần phải nói rằng trong nhiều trường hợp chúng ta chưa thê xây
dựng một thuật toán nào thực sự hữu hiệu để giải bài toán tối ưu, mà cho tới nay việc tìm nghiệm của chúng vẫn phải dựa trên mô hình liệt kê toàn bộ các cầu hình có thể (Xi, Xa, Xa) và đánh giá, tìm ra cấu hình tốt nhất Việc tìm cấu hình theo cách này
còn có tên gọi là phương pháp vét cạn Chính nhờ kỹ thuật này cùng với sự phát triển
của máy tính điện tử mà nhiều bài toán khó đã tìm thấy lời giải
Mô hình thuật toán quay lui là tìm kiếm trên một cây phân cấp Nếu giả thiết rằng mỗi nút nhánh của cây chỉ có 2 nút con thì cây có độ cao n sẽ có tới 2" nút lá, con số này lớn hơn rất nhiều lần so với kích thước đữ liệu đầu vào n Chính vì vậy mà nếu như ta có thao tác thửa trong việc chọn x¡ thì sẽ phải trả giá rất lớn về chi phi
thực thi thuật toán (độ phức tạp tính toán hàm mũ) bởi quá trình tìm kiếm “dư thừa” trong các bước chọn kế tiếp Xi+, Xi+2, Khi đó, một vấn dé đặt ra là trong quá trình
liệt kê lời giải ta cần tận dụng những thông tin đã tìm được đề loại bỏ sớm những phương án chắc chắn không phải tối ưu Kỹ thuật đó gọi là kỹ thuật đánh giá nhánh cận trong tiến trình quay lui
- Thu thập tài liệu: Tìm các cuốn sách, các tài liệu viết về nội dung giải toán
bằng phương pháp nhánh cận Các tài liệu viết về các ngôn ngữ lập trình Các bài toán tiêu biểu có thể giải được bằng phương pháp nhánh cận
- Nghiên cứu lý thuyết: Trên cơ sở các tài liệu thu thập được, tiến hành đọc,
phân loại và viết báo cáo
- Cài đặt chương trình: Cài đặt chương trình cho các thuật toán đã được xây dựng, thực hiện và kiểm tra chương trình
5 BO CUC CUA DE TAI
Chương 1 Giới thiệu về phương pháp lập trình đệ quy
Nội dung của chương là giới thiệu những khái niệm cơ bản về đệ quy, các bước để giải bài toán bằng phương pháp đệ quy và lập trình đệ quy trên các cấu
Trang 10Chương 2 Kỹ thuật đệ quy nhánh cận
Nội dung của chương là đi tìm hiểu bài toán tối ưu tổ hợp Cách giải một bài
toán bằng phương pháp nhánh cận Trình bày về mối quan hệ giữa phương pháp quy
hoạch động và đệ quy nhánh cận
Chương 3 Áp dụng phương pháp đệ quy nhánh cận để giải các bài toán học sinh giỏi
Nội dung của chương là giới thiệu một số bài toán, phân tích và giải bài toán đó bằng phương pháp đệ quy nhánh cận, giới thiệu một số bài toán tương tự (gợi ý cách giải)
6 TONG QUAN TAI LIEU THAM KHẢO
Khi trién khai nghién ctru dé tài tôi đã tham khảo các tài liệu về toán rời rạc, lý thuyết dé thi, cấu trúc đữ liệu và giải thuật, toán ứng dụng, các giải thuật nâng cao và
Trang 11Chương 1 GIỚI THIỆU VẺ PHƯƠNG PHÁP LẬP TRÌNH ĐỆ QUY Đệ quy mặc dù không nằm trong nội dung chương trình tin học phố thông nhưng là một trong những kỹ thuật lập trình thường được sử dụng trong các kỳ thi học sinh gidi, Olympic, tin học trẻ
Chương này sẽ giới thiệu về phương pháp lập trình đệ quy, bao gồm các phần: giới thiệu về đệ quy, các bước để giải bài toán bằng phương pháp đệ quy và một số
vi du minh hoa
1.1 GIOI THIEU VE DE QUY
Đôi khi chúng ta có thê quy việc giải bài toán với tập các dữ liệu đầu vào xác định về việc giải cùng bài toán đó nhưng với các giá trị đầu vào nhỏ hơn Chẳng hạn, nhìn chung bài toán tính giai thừa của N, ta có thể đưa về bài toán tinh N*(N-1)! Khi
việc phân tích như vậy thực hiện được thì lời giải bài toán ban đầu có thể tìm được
bằng một dãy các phép phân tích cho tới những trường hợp mà ta có thể dễ đàng nhận được lời giải của bài toán Ta sẽ thấy rằng việc phân tích liên tiếp bài toán ban đầu cho phép dẫn tới bài toán có đữ liệu đầu vào nhỏ hơn, được áp đụng trong một lớp rất rộng các bài toán
Định nghĩa: Một thuật toán được gọi là đệ quy nếu nó giải bài toán bằng cách phân tích liên tiếp bài toán ban đầu tới bài toán cũng như vậy nhưng có dữ liệu đầu vào là tiếp cận với trường hợp suy biến
Trong lập trình, chương trình con đệ quy là chương trình con có nội dung gọi đến chính nó Một chương trình đệ quy thì không thể gọi đến chính nó mãi mãi mà phải có điểm dừng mà ta gọi là trường hợp suy biến
Ví dụ 1 Tính
1 nếu n =0 (trường hợp suy biến) m= tn (DI nếu n>0 (trường hợp chung) Function Giaithua(n:integer):integer;
Trang 12Ifn=0 then giaithua:=1
Else giaithua:= n* giaithua(n-1);
End;
Vi du 2 Tinh
1 nếu n =0 (trường hợp suy biến) oe \, am1 nếu n>0 (trường hợp chung) Function Luythua(a:integer; Var n:integer): longint; Begin If n=0 then Luythua:=1 Else luythua:=a*luythua(a,n- 1); End; * Xác định độ phức tạp của thuật toán - Xác định phép toán tích cực:
Kiểm tra “n=0” trong lệnh If
+ Gọi gín) là số lần thực hiện phép toán tích cực của chương trình con Luythua(a,n) => g(n-l) là số lần thực hiện phép toán tích cực của chương trình con Luythua(a,n-1) gm—-1)+1 néun>0 1 niếu = 0 g0) = {
Giai bai toan trén ta co g(n) =n+1
Vậy độ phức tạp thuật toán là T(n) =O(g(n))=O(n+1) = O(n)
" Phân tích hoạt động của hàm Luythua(a, n) một cách hình thức: « Gồm 2 pha:
Trang 13Ví dụ Cho a= 6, n=3, hãy theo vết chạy của hàm Luythua(6, 3) Luythua(6,3) Return 1 Hinh 1.1 Minh hoa tién trinh tính toán đệ quy giá trị 6 > Két qua Luythua(6,3)= 6*6*6 Luu ¥: Trong hinh 1.1 cdc cung nét lién la pha tién va cdc cung nét đứt là pha lùi
Các thành phần của một định nghĩa theo cách đệ quy
+ Thành phẩn 1: Thành phần không đệ quy (trường hợp suy biến, điều kiện dừng)
- Chứa những trường hợp đơn giản nhất dé xây dựng nên định nghĩa * Thanh phan 2: Thanh phan đệ quy (trường hợp đệ quy)
- Chứa những quy tắc, công thức đề tạo đối tượng mới từ những đối tượng trước đó
Trang 141.2 CÁC BƯỚC ĐỂ GIẢI BÀI TOÁN BẰNG PHƯƠNG PHÁP ĐẸ QUY
Đề thiết kế một thuật toán đệ quy gồm 3 bước:
Bước 1 Tham số hoá bài toán
Bước 2 Phân tích trường hợp chung (biêu diễn bài toán đưới dạng bài toán cùng loại nhưng khác phạm vi giải quyết)
Bước 3 Xác định trường hợp suy biến
Lưu ý: Khi viét mét ham (Function) dé quy thì phải trả giá trị ở mọi ngóc ngách, có IF thì phải có ELSE Còn đối với thủ tục (Procedure) đệ quy có thể ta không cần phải làm gì
Ví dụ 1 Tính a"
Bước 1 Tham số hoá bài toán:
Luythua(a,n)=a" = a*a™! = a*Luythua(a,n-1) Buéc 2 Phan tich trrong hop chung: If n>0 then Luythua(a,n-1) Bước 3 Xác định trường hợp suy biến: If n=0 then Luythua:=1; Function Luythua(a:real; n:byte): Real; Begin If n=0 then Luythua:=1 Else Luythua:=a*Luythua(a,n- 1); End; * Xây dựng thuật toán đệ quy trên dữ liệu mảng: Ví dụ 2 Tìm kiếm nhị phân:
Trang 15Bước 1 Tham số hoá bài toán:
TKNP(a,x,1,g — 1) nếu x < a[g]
TKNP(a,x,1,n) = $ TKNP(a,*x, g + 1,c) nếu x > a[g]
TKNP =g néu x = a[g]
Bước 2 Phân tích trường hợp chung: If x<a[g] then TKNP:=TKNP(a,x,d,g-1) If x>a[g] then TKNP:=TKNP(a,x,g+1,c)
Bước 3 Xác định trường hợp suy biến: If x=a[g] then TKNP:=g hoặc d>c thì TKNP:=0 Function TKNP(a:mang; x:integer; d,c:word):word; Var g:word; Begin If d>c then TKNP:=0 Else Begin g:=(dtc) div 2; If a[g] =x then TKNP:=g Else If x<a[g] then TKNP:=TKNP(a,x,d,g-1) Else TKNP:=TKNP(a,x,g+1,c); End; End;
Ví dụ 3 Xoá các phần tử bang x trong day sé ai, a2 an Buée 1 Tham sé hoa bai toan:
Kiểm tra a[n] =x? nếu đúng thì n:=n-l; Xoa(x);
Trang 17* Xây dụng thuật toán đệ quy trên danh sách liên kết:
Ví dụ 4 Viết hàm đệ quy để tính tổng trường Info của tất cả các nút thuộc danh sách F Trong đó khai báo được cho trước như sau:
Type TroNut=“Nut; Nut = Record
Info: Integer; Next:TroNut;
End;
Var F:TroNut; {danh sach F } Function Tong(F:TroNut): Integer;
Begin
If F=Nil then Tong:=-0 Else Tong:=F^.Info +Tong(F^.NexÐ):
End;
* Xây dựng thuật toán đệ quy trên cây
Ví dụ 5 Viết chương trình con đệ quy để tìm chiều cao của một cây nhị phân lưu trữ móc nối Trong đó khai báo được cho trước như sau:
Type TroNut =“Nut; Nut = Record
Info:integer; Left,Right:TroNut;
End;
Var T:TroNut,; {cay T}
Function Chieucao(T:TroNut): Word; Begin If T=nil then Chieucao:=0
Else Chieucao:=max(Chieucao(T”.Left),Chieucao(T”.Right))+1;
Trang 181.3 GIỚI THIỆU PHƯƠNG PHÁP VÉT CẠN
Phương pháp vét cạn là một kỹ thuật của đệ quy quay lui Ý tưởng của phương pháp vét cạn theo nghĩa thông thường là xét hết mọi đối tượng hay mọi trường hợp Trong lập trình, vét cạn là phương pháp được dùng khi không còn phương pháp nào hiệu quả hơn có thể sử dụng được Phương pháp vét cạn được mô tả chung như sau:
- Bai toán: Có một tập các ứng viên và một hàm ƒ đề đánh giá/cho điểm các ứng viên Hãy tìm ứng viên được đánh giá/có điểm cao nhất
- Phương pháp giải: Duyệt tất cả các ứng viên, tính điểm cho từng ứng viên, sau đó lấy ứng viên có điểm cao nhất
Phương pháp vét cạn tưởng rằng tầm thường nhưng thực sự không tầm thường chút nào bởi vì không phải trong trường hợp nào các ứng viên cũng dễ nhận thấy và đã “xếp hàng” sẵn để được duyệt Nghĩa là, van dé trong phương pháp vét cạn là làm
sao để liệt kê được tất cả các ứng viên Một khi đã liệt kê được các ứng viên, việc
chấm điểm cho từng ứng viên và chọn ra ứng viên có điểm cao nhất chỉ còn là việc làm đơn giản
Một phương pháp hay được dùng để liệt kê các ứng viên là tổ chức không gian ứng viên theo một cấu trúc cây, mỗi ứng viên trên một nút (thường là lá) của cây Đặc điểm của cây biểu điễn không gian ứng viên là các ứng viên trên
các nút có quan hệ cha - con hoặc anh - em giống nhau ở một bộ phận nào đó
Một khi cấu trúc cây biểu diễn không gian ứng viên được thiết lập, chúng ta có
thể áp dụng thủ tục duyệt cây (theo chiều rộng hoặc theo chiều sâu) dé liệt kê
các ứng viên Cây biêu diễn không gian ứng viên có thê rất lớn và sẽ mắt nhiều thời gian để tạo, cũng như yêu cầu nhiều không gian để lưu trữ Tuy nhiên, cây
này chỉ mang tính trừu tượng, làm cơ sở cho việc duyệt (chọn nút tiếp theo được thăm), mà không phải được tạo ra và lưu trữ tất cả
Các bước thiết lập cây biểu diễn không gian ứng viên được mô tả chung
như sau:
Trang 191 Xác định các tinh chất của ứng viên dùng đề phân loại ứng viên
2 ới tính chất thứ nhất, phân hoạch các ứng viên theo tính chất này, nghĩa là chia tập ứng viên thành các tập con theo đó các phần tử thuộc cùng một tập con giống nhan ở tính chất thứ nhất, hai phần tử thuộc hai tập con khác nhau sẽ khác nhan ở tính chất thứ nhất Tạo các cây con từ gốc, mỗi cây con hương ứng với một
tập con vừa nhận được
3 Với mỗi tập con, sử dụng tinh chất thứ hai đề phân hoạch tập con này Kết quả thu được là các tập con nhỏ hơn Từ gốc của cây con tương ứng với tập con đang xét, tạo các nhánh tương ứng với các tập con nhỏ hơn
4 Quá trình cứ tiếp tục như vậy cho đến khi chúng ta xét hết các tính chất của ứng viên và thu được một cây biểu điễn không gian ứng viên
Thuật toán quay lui thường được sử dụng trong phương pháp vét cạn, tức là nó cho phép dùng để giải bài toán liệt kê các cấu hình Thuật toán này làm việc theo cách:
- Mỗi cầu hình được xây dựng bằng cách xây dựng từng phần tử - Mỗi phần tử được chọn bằng cách thử tất cả các khả năng
Giả sử cấu hình hình cần liệt kê có dang (xì, x›, xa), khi cần xác định xi, ta
giả sử đã xác định được i-1 thành phan: X1, Xa, Xi Dé x4c dinh thanh phan x ta
duyệt tất cả các khả năng có thể có của nó Với mỗi khả năng j ta luôn kiểm tra xem j có được chấp nhận không?
- Nếu chấp nhận j, thì xác dinh xi theo khả nang j Tiếp đến kiểm tra, néu i<n thi
ta tiến hành xác định xi, ngược lại (=n) thì ta được một lời giải Rồi kiểm tra kha
năng tiếp theo của xi
- Nếu tất cả các khả năng của j không có khả năng nào được chấp nhận thì
quay lại bước trước để xác định lại xi1 (Cơ chế đệ quy giúp có thể thực hiện được
điều này)
Trang 20Procedure Try(), {thử xem xi sé nhan gia tri nao} Begin
For <M6i kha nang j cia x> do Begin If <chap nhan> then
Begin <Xac dinh x; theo j>;
If i=n then <Ghi nhan mot loi giai> Else Trya+1); [<Huy viéc xac dinh x; theo j>;] End; End; End; BEGIN [Init {khởi tạo}] Try(1); END
1.4 GIAI MOT SO BAI TOAN BANG CACH SU DUNG DE QUY QUAY LUI
Vấn đề chính trong sử dụng phương pháp vét cạn để giải toán là liệt kê các ứng viên Một phương pháp hay được sử dụng là thiết lập cây biểu diễn không gian ứng viên rồi áp dụng một thủ tục đuyệt cây đề liệt kê các ứng viên Phương pháp này gợi ý cho chúng ta sử dụng một số tinh chất dé phân loại ứng viên và thủ tục thiết lập cây biểu diễn không gian ứng viên
Vét cạn là cơ sở cho hai phương pháp là quay lui và nhánh cận Cả vét cạn, quay lui và nhánh cận đều thực hiện duyệt cấu trúc cây biểu diễn không gian ứng viên Điểm phân biệt giữa vét cạn, quay lui và nhánh cận là trong quá trình duyệt (theo chiều sâu) cây, phương pháp quay lui sử dụng một hàm diéu kiện, tại mỗi
nút nếu hàm điều kiện không thỏa mãn, toàn bộ cây con có gốc tại nút hiện tại
được bỏ qua; phương pháp nhánh cận sử dụng một hàm fính cận để tính trước
điểm tối đa (cận) có thể đạt được đối với các ứng viên thuộc cây con có gốc tai
Trang 21nút hiện tại, nếu cận này không cao hơn điểm của ứng viên đã biết thì toàn bộ cây
con có gốc tại nút hiện tại được bỏ qua Có thể tóm tắt hai phương pháp quay lui và nhánh cận theo các công thức: Vét cạn + Hàm điều kiện — Quay lui, Vét cạn + Hàm tính cận —= Nhánh cận Theo đó: - Vét can (Brute Force) + Tìm hết tất cả các lời giải + Độ phức tạp tính toán: hàm mii - Nhánh cận (Branch and Bound)
+ Chỉ tìm những lời giải có lợi
+ Cải tiến thời gian thực hiện
1.4.1 Bài toán liệt kê các dãy nhị phần
Bài toán: Biểu diễn dãy nhị phân độ dài N dưới dạng dãy xi Xn
Yêu cầu: Viết chương trình liệt kê tất cả dãy nhị phân có độ dài bằng N Dữ liệu vào: Cho trong file văn bản NHIPHAN.INP, có cấu trúc như sau:
- Dòng 1: Ghi số nguyên dương N (2 <N < 100)
Trang 22Thuật toán:
Ta sẽ liệt kê các đấy này bằng cách thử dùng các giá tri {0, 1} gan cho xi Voi mỗi giá trị gan cho xị lại thử các giá trị có thé gan cho xin,
Sau đây là thủ tục quay lui liệt kê các dãy nhị phân Chương trình hoàn thiện
được minh hoạ ở phần phu lục
Procedure Try(1:integer); /⁄/ Thử các cách chọn x[1] Var j:byte;
Begin
For j:=0 to 1 do // Xét các giá trị j có thê gán cho x[i] Begin // Với mỗi giá trị đó
x[]:=1: //Thử đặt xỊ[I]
ifi=N then in KQ // Néui=N thi in kết qua ra file
Trang 231.4.2 Bài toán liệt kê các hoán vị của tập các số nguyên 1,2, N
Bài toán: Viết chương trình nhập số nguyên dương N từ bàn phím, in ra màn
hình tất cả các hoán vị của tập 1,2, N
Thuật toán:
Khi cần xác định xị, ta giả sử đã xác định được 1-l thành phan: X1, X2, , Xi Dé
xác định thanh phan xi, ta duyệt tất cả các khả năng có thể có của nó Với mỗi khả năng j ta luôn kiểm tra xem j có được chấp nhận không?
* Nếu chấp nhận j, thì xác định x¡ theo khả năng j
Tiếp đến kiểm tra, nếu ¡ < n thì ta tiến hành xác định x¡:1, ngược lại (in) thì ta
được một lời giải Rồi kiểm tra khả năng j tiếp theo của x¡
Nếu tất cả các khả năng của j không có khả năng nào được chấp nhận thì quay
lại bước trước để xác định lai xin (Cơ chế đệ quy giúp có thể thực hiện được điểu
này) Dưới dây là thủ tục liệt kê các tập hoán vị n phần tử bằng thuật toán quay lui
Trang 24b[j]:=true; end;
end;
1.5 TIEU KET CHUONG 1
Chương này đã dé cập đến các nội dung cơ bản về kỹ thuật đệ quy quay lui, các bước để giải bài toán bằng phương pháp đệ quy và lập trình đệ quy trên các
cấu trúc dữ liệu
Ở chương tiếp theo, ta sẽ tìm hiểu về mối quan hệ giữa phương pháp đệ quy nhánh cận với phương pháp quy hoạch động
Trang 25Chương 2 KỸ THUẬT ĐỆ QUY NHÁNH CẬN
Hiện nay, trong các kỳ thi học sinh giỏi tin học, các lớp bài toán về tối ưu hố
ln được ưu tiên lựa chọn vì tính ứng dụng vào thực tiễn cao
Có rất nhiều phương pháp để giải quyết lớp các bài toán tối ưu Tuỳ từng bài
toán cụ thể mà ta lựa chọn một phương pháp để áp dụng nhằm đạt được hiệu quả (về
tốc độ, về bộ nhớ) Đệ quy nhánh cận là một trong những phương pháp có thê lựa chọn để giải quyết bài toán này Đề hiểu rõ hơn về phương pháp đệ quy nhánh cận, ở chương này sẽ tìm hiểu về mối quan hệ giữa phương pháp đệ quy nhánh cận và phương pháp quy hoạch động
2.1 BÀI TOÁN TÓI ƯU TỎ HỢP
Trong rất nhiều vẫn để ứng dụng thực tế của tổ hợp, các cầu hình của một tổ
hợp còn được gán cho một giá trị bằng số để đánh giá giá trị sử dụng của cấu hình
đối với một mục đích sử dụng cụ thể nào đó
Khi đó xuất hiện bài toán: Hãy lựa chọn trong số các cấu hình của một tổ hợp
chấp nhận được cấu hình có giá trị sử đụng tốt nhất Các bài toán như vậy chúng ta sẽ gọi là bài toán tối ưu tô hợp Dưới đạng tổng quát bài toán tối ưu tổ hợp có thê phát
biểu như sau:
Tìm giá trị cực tiểu (hay cực đại) của hàm f(x), voi điều kiện xeD, trong đó D
là tập hữu hạn các phân tử
Ham f(x) được gọi là hàm mục tiêu của bài toán, mỗi phần tử xeD được gọi là
một phương án, còn tập D gọi là tập các phương án của bài toán Nếu x là một phương án, thì f(x) được gọi là giá của phương án
Tập D được mô tả như là tập các cấu hình tổ hợp thỏa mãn một số tính chất cho trước nào đó
Phương án x*eD đem lại giá trị nhỏ nhất (lớn nhất) cho hàm mục tiêu được gọi
Trang 26Một trong những phương pháp hiển nhiên nhất đê giải bài tốn tối ưu tơ hợp đặt ra là: Trên cơ sở các thuật toán liệt kê tổ hợp ta tiến hành duyệt từng phương án của
bài toán, đối với mỗi phương án ta đều tính giá trị hàm mục tiêu tại đó, sau đó so sánh
giá trị hàm mục tiêu tại tất cả các phương án được liệt kê để tìm ra phương án tối ưu Phương pháp xây dựng theo nguyên tắc như vậy có tên gọi là phương pháp duyệt
toàn bộ Duyệt toàn bộ là khó có thể thực hiện được ngay cả trên những máy tính điện
tử hiện đại nhất
Ví dụ đề liệt kê hết 15! = 1307674368000 hoán vị trên máy tính điện tử với tốc
độ tính toán I tỷ phép tính một giây, nếu đề liệt kê một hoán vị cần phải làm 100 phép
tính, thì ta cần một khoảng thời gian là 130767 giây, lớn hơn 36 giờ Vì vậy cần phải
có những biện pháp nhằm hạn chế việc “duyệt toàn bộ” thì mới có hy vọng giải được
các bài toán tối ưu tổ hợp thực tế
Tất nhiên để có thé đề ra những biện pháp như vậy cần phải nghiên cứu kỹ tính chất của bài toán tối ưu tổ hợp cụ thê Trong một số trường hợp cụ thê ta có thể xây dựng những thuật toán hiệu quả để giải bài toán đặt ra Tuy nhiên phải nhấn mạnh rằng trong nhiều trường hợp (ví dụ bài toán người du lịch, bài toán cái túi, bài toán đồ thị con đầy đủ cực đại) chúng ta chưa thể xây dựng được phương pháp hữu hiệu nào khác ngoài phương pháp duyệt toàn bộ Khi đó, một vấn để đặt ra là trong quá trình liệt kê lời giải ta cần tận dụng các thông tin đã tìm được để loại bỏ những phương án chắc chắn không phải tối ưu
Trong phần tiếp theo ta sẽ xét một sơ đồ tìm như vậy đề giải các bài toán tối ưu
tổ hợp với tên gọi là thuật toán đệ quy nhánh cận
2.2 CÁCH GIẢI MỌT SÓ BÀI TOÁN BẰNG PHƯƠNG PHÁP ĐẸ QUY NHÁNH CẬN
Phương pháp đệ quy nhánh cận được Land A.H và Doig A.G xây dựng năm 1960 nhằm giải bài toán qui hoạch nguyên Đến 1963 được Little J.D, Murty K.G, Sweeney D.W và Karen C sử dụng thành công để giải bài toán người du lịch Đây là thuật toán ứng đụng rộng rãi để giải các bài toán tối ưu khó
Trang 27Nhánh cận là kỹ thuật xây dựng cây tìm kiếm phương án tối ưu, nhưng khơng xây đựng tồn bộ cây mà sử dụng giá trị cận đề hạn chế bớt các nhánh Cây tìm kiếm phương án có nút gốc biểu dién cho tập tat cả các phương án có thể có, mỗi nút lá biểu diễn cho một phương án nào đó, nút n có các nút con tương ứng với các khả năng có thê lựa chọn tập phương án xuất phát từ n Kỹ thuật này gọi là phân nhánh Ý tưởng chính của nó như sau:
Trong quá trình duyệt ta luôn giữ lại một phương án mẫu (có thể xem là lời giải
tối ưu cục bộ - chẳng hạn có giá nhỏ nhất tại thời điểm đó) Đánh giá nhánh cận là
phương pháp tính giá của phương án ngay trong quá trình xây dựng các thành phần của phương án để đánh giá được theo hướng đang xây dựng có thể tốt hơn phương án mẫu hay không, nếu không, ta lựa chọn theo hướng khác
Với mỗi nút trên cây ta sẽ xác định một giá trị cận Giá trị cận là một giá trị gan
Với giá của các phương án Với bài toán tìm min ta sẽ xác định cận dưới, còn với bài toán tìm max ta sẽ xác định cận trên Cận dưới là giá trị nhỏ hơn hoặc bằng giá của phương án, ngược lại cận trên là giá trị lớn hơn hoặc bằng giá của phương án
Ta sẽ mô ta tư tưởng của thuật toán trên mơ hình bài tốn tối ưu tổ hợp tổng
quát sau: min{ƒ(x):xeD oR"
trong dé D la tap httu han phân tử, là miền các phương án: x 1a mot phuong an
thuộc mién D
Phương pháp nhánh cận được mô tả như sau:
Từ miền D ta phân nhánh thành hai miền D¡, D›, trên mỗi nhánh ta xây dựng
hàm ø xác định trên các mién Dj, D> dé tính giá trị cận dưới
Gọi /, là cận dưới của nhánh D\, gọi Ø, là cận dưới của nhanh Do
So sánh giá trị các cận đưới /, và Ø,,Nếu / < /, thì bước tiếp theo sẽ chọn
nhanh D, dé tiép tục, ngược lại thì chọn nhanh D2
Trang 28các nhánh Dị và Da Tương tự ta gọi J¡i là cận dưới của nhánh Dị, gọi Biz la can dưới của nhánh ha Lại tiếp tục so sánh các giá trị cận dưới Bi va Biz để chọn nhánh
cần phát triển trong bước tiếp theo Quá trình trên cứ lặp đi lặp lại cho đến khi không thê phân nhánh được nữa, lúc này ta có phương án tối ưu tạm thời trong quá trình tìm nghiệm của bài toán
Gọi B là nghiệm tối ưu tạm thời, lúc này thuật toán nhánh cận sẽ tiếp tuc voi
những nhánh còn lại sao cho giá tri của hàm ø tại đó nhỏ hơn §”
Thuật tốn phân nhánh của phương pháp nhánh cận có thể minh họa bằng
sơ đô:
Hình 2.1 Sơ đồ thuật toán phân nhánh của phương pháp nhánh cận Ta xây dựng thuật toán nhánh cận bằng thủ tục đệ quy tổng quát như sau: Procdure Try(k)
(* Phát triển phương án bộ phận (a1, a2, .ax-1) theo thuật toán quay lui có kiểm tra cận dưới trước khi tiếp tục phát triển phương án*)
Begin
For ax € Axdo {V6i Ax la tap cac giá trị có thể chấp nhận của ax}
Trang 29¡f <chấp nhận ax> then Begin Xk:=Ak; In = kthen <Cập nhật / = else if £(4,4,, 4,)< F then Try(k+): End; End;
Khi đó thuật toán nhánh cận được thực hiện nhờ thủ tục sau:
Procedure Nhanh can; Begin J = +h; // phương án tôi nhất (* Nếu biết một phương án X nào đó thì có thể đặt ƒ = ƒ (*}*) Try(1): if f <+h then
<f la giá trị tối ưu, x là phương án tối ưu> else <Bài toán không có phương án>
End;
2.2.1 Bài toán người du lịch
2.2.1.1 Phát biểu bài toán
Trang 30= CỊ[j ¡] là chi phi phải trả khi đi đoạn đường trực tiếp tử thành phố ¿ đến thành phố 7 Giả thiét rang C[i, i] = 0 Vi, C[i, j] = + © nếu không có đường đi trực tiếp từ thành
phố z đến thành phố /
Một người khách du lịch xuất phát từ thành phố 1, muốn đi thăm tất cả các thành phố còn lại mỗi thành phố đúng một lần và cuối cùng quay lại thành phố I
Yêu cầu: Hãy chỉ ra một hành trình du lịch sao cho chỉ phí phải trả là ít nhất Dữ liệu vào: Cho trong file văn bản DULICH.INP có cấu trúc như sau:
- Dòng 1: Ghi hai số nguyên dương n, m Trong đó n là số thành phố (1 <n < 20) và m là số lượng tuyến đường trong mạng lưới giao thông
- m dong tiếp theo: mỗi dòng ghi ba số ¡, j, k Trong đó ¡, j là số hiệu hai thành phố có đường đi trực tiếp và k là chi phí đi trên quãng đường từ ¡ tới j (0 < k< 100)
Dữ liệu ra: Ghi ra file văn bản DULICH.OUT theo cấu trúc như sau:
- Dòng 1: Ghi số nguyên dương t là tổng chi phí của hành trình tìm được
- Dòng 2: Ghi các số hiệu các thành phố của hành trình tìm được, các số được
Trang 31DULICH.INP DULICH.OUT 510 10 1210 193953923947 132 1 142 159 239 242 252 3410 B15 2 458 221.2 Thuật toán Cố định thành phố xuất phát là v(1), bài toán người du lịch dẫn về bài toán: Tìm cực tiêu của hàm
ƒ(%;.x; x„)=e[1.x; |+e[x;.x; |+ +e[x„ ¡.x„|+e[x, 1]—> min, 2 n n? với điều kiện La x,) là hoán vị của các s6 2, 3, ., n
Ký hiệu C,„„ = min{e[¿ 7] |i, 7 =1,2 n,7 # j}1a chi phi di lại nhỏ nhất giữa
các thành phố, va C = { cfij] | iy = 1,2, ,.n} la ma tran chi phi
Mỗi hành trình v = v(1)->v(2)-> >v(n-1)>v(n) > v(1) có thể viết dưới dạng
v_= (w(1),v)) (v(2).vG)) (v(n-1),v(n)), (v@n),v(1)) Trong đó mỗi thành phần (v1), v)) gọi là một cạnh của hành trình
Duyệt quay lui: xz có thê chọn một trong các thành phố mà xị có đường đi tới
(trực tiếp), với mỗi cách thử chọn xa như vay thi x3 co thể chọn một trong các thành
phố mà xa có đường đi tới (ngoài xi) Tổng quát: x¡ có thé chọn 1 trong các thành phố chưa đi qua mà từ x¡¡ có đường đi trực tiếp tới (1 <I<n)
Nhánh cận: Khởi tạo cấu hình Best có chỉ phí =+h Với mỗi bước thử chọn xị xem chỉ phí đường đi cho tới lúc đó có nhỏ hơn Chỉ phí của cấu hình Best không), nếu không nhỏ hơn thì thử giá trị khác ngay bởi có đi tiếp cũng chỉ tốn thêm Khi thử được 1 giá trị xn ta kiểm tra xem xạ có đường đi trực tiếp về I không? Nếu có đánh
Trang 32giá chỉ phí đi từ thành phố 1 đến thành phố xa cộng với chỉ phí từ xa đi trực tiếp về 1,
nếu nhỏ hơn chỉ phí của đường đi Best thì cập nhật lai Best bằng cách đi mới
Sau thủ tục tìm kiếm quay lui mà chỉ phí của Best vẫn bằng +h thì có nghĩa nó
không tìm thấy một hành trình nào thoả mãn điều kiện vẻ đề bài để cập nhật Best, bài
Trang 33Dữ liệu vào từ file ATM.INP có dạng
- Dòng đầu 2 số n va S
- Dòng thứ 2 gồm n số tr tl, t2 tn
Kết quả file ATM.OUT có dạng: Nếu có thê trả số tiền ding bang S thì đưa ra số tờ ít nhất cần tra va đưa ra cách trả, nếu không ghi -1 ATM.INP ATM.OUT 10 390 5 200 10 20 20 50 50 50 50 100 100 20 20 50 100 200 2222 Thuật toán
Như ta đã biết nghiệm của bài toán là 1 dãy nhị phân độ dài N Giả sử đã xây
dựng được k thành phần ( XI, Xa, Xx), đã trả được Sum và sử dụng c tờ Dé đánh giá được các nghiệm mở rộng của (Xi, Xa, Xx) ta nhận thấy:
- Con phai tra: S — sum
Trang 34sum:=sum+x[i]*t[i];
c:=c+];
if (i=n) then Capnhat
else if sum<=s then Nhanhcan(it+1); sum:=sum-x[1]*t[1]; c:=C-J; end; end; 2.3 SO SÁNH GIỮA PHƯƠNG PHÁP DE QUY NHANH CAN VỚI PHƯƠNG PHÁP QUY HOẠCH ĐỌNG
Bài toán đặt ra của phương pháp đệ quy nhánh cận là rất giống với phương pháp quy hoạch động Cả hai phương pháp này đều dùng dé giải các bài toán tối ưu Cả hai phương pháp đều sử đụng lời giải của các bài toán có kích thước bé hơn, đồng đạng với bài toán ban đầu để đưa ra lời giải của bài toán ban đầu Phương pháp quy hoạch
động gọi thực hiện các bài toán có kích thước bé trước rồi lưu lại kết quả để giải các
bài toán có kích thước lớn hơn Do vậy khi giải bài toán theo quy hoạch động nếu dùng một phương pháp gồm nhiều bước tiến hành thì điều kiện cần để giải pháp này tối ưu là nó được xây đựng từ nghiệm tối ưu của những bước trước
Thuật toán đệ quy nhánh cận là thuật toán tìm phương án tối ưu của bài toán bằng cách kết hợp phương pháp quay lui với hàm tính cận để lựa chọn một phương án trong tập hợp tất cả các phương án của bài toán để tìm ra phương án tôi ưu Trong nhiều bài tốn, khơng gian các phương án quá lớn, đệ quy nhánh cận giúp tìm ra kết quả tối ưu nhưng độ phức tạp lớn, thường là độ phức tạp tính toán hàm mũ trong khi phương pháp quy hoạch động thường độ phức tạp tính toán là đa thức
Vì vậy ưu điểm của phương pháp đệ quy nhánh cận là chắc chắn tìm ra lời giải
(nếu có), nhưng nhược điểm của nó là chỉ phí về mặt thời gian thực hiện lớn Còn
phương pháp quy hoạch động có ưu điểm là độ phức tạp tính toán tốt nhưng nhược
Trang 35điểm của nó là không dé dé tìm ra thuật toán, với một số bài toán có thể sẽ không tổn
tại cách giải quyết theo thuật toán quy hoạch động
Trong phương pháp đệ quy, để thiết lập một lời giải đệ quy người lập trình cần
xây đựng ba bước đề thiết kế một lời giải là:
Bước 1 Tham số hoá bài toán
Bước 2 Phân tích trường hợp đệ quy Bước 3 Xác định trường hợp suy biến
Một cách tương tự, với đa số các bài toán về quy hoạch động, chúng ta có thể
thực hiện theo quy trình sau: Bước 1 Phân tích bài toán
Ta tìm cách đưa bài toán về dạng giải được bằng quy hoạch động, nghĩa là biểu
diễn bài toán dưới dạng một bài toán nhiều mức, nhiều giai đoạn có quan hệ khắng
khít với nhau Từ bài toán đã cho đưa nó về các bài toán con đồng dạng
Tương tự với tham số hoá bài toán trong đệ quy Cần lựa chọn và xác định những tham số cân thiết, các đại lượng là rời rạc
Xét ví dụ về đấy Fibonacci Sử dụng đệ quy ta xây dựng hàm F có một tham số thuộc kiểu số nguyên Phân tích bài toán theo phương pháp quy hoạch động ta thấy dé tính được F() cần dựa tính F(i-1) va F(i-2) là các bài toán con đồng đạng Vì vậy ta cũng xây dựng hàm F có 1 tham số nguyên là n
Function F(n: integer): integer; Bước 2 Xây dựng giải pháp đệ quy
Đây là bước thiết lập mối quan hệ giữa các giai đoạn với nhau
Trang 36Đối với bài tốn dãy Fibonacci từ thơng tin bài toán là F(1) = F(2) = 1 va F(n) = F(n-]1) + F(n-2) ta có được giải pháp đệ quy sau:
F(n — 1) + F(mn — 2) nếu n > 2 1 niễu n = 1 hoặc = 2
FQ) ={
Bước 3 Lap bang
Dựa vào công thức truy hồi để tìm lời giải của các bài toán tương ứng với các giai đoạn đã chia, các giá trị này sẽ được lưu trữ vào bảng Bảng có thé thiết lập như mảng I chiều, 2 chiều, Thông thường nếu tham số hình thức là 1 tham số thì dùng mảng l chiều, nếu 2 tham số thì dùng mảng 2 chiều Thứ tự điển vào bảng cũng chính là thứ tự giải các bài toán từ thấp đến cao nhưng phải đảm bảo sao cho các kết quả điền vào bảng cuối cùng sẽ cho ta giá trị tối ưu của bài toán ban đầu và phương án tối ưu của giai đoạn cuối
Với bài toán Fibonacci, ta thấy có 1 tham số hình thức nên sử dụng mảng 1 chiéu a (array[1 max] of integer) dé tinh:
ali] = F(i) tưới ¡ = 1 m
Cu thé: a[1] = a[2] va afi] = afi — 1] + ali — 2]; voii = 3 n Các giá trị sẽ được điền vào theo tht ty tir a[1] dén a[n]
Bước 4 Tổng hợp kết quả
Đây là bước kiến tạo một lời giải cho bài toán từ các thông tin đã tính toán Từ trạng thái cuối cùng ta biết được phương án tối ưu của giai đoạn cuối và đo đó biết được trạng thái tối ưu của giai đoạn ngay trước nó Cứ tiếp tục như vậy ta biết được toàn bộ phương án tối ưu của từng giai đoạn từ đầu đến cuối
Với bài todn Fibonacci Phuong án cuối cùng là z[z] nên bước tổng hợp kết quả
la: F(n) = a[n];
D6 phic tap tinh toan: O(n)
Từ bốn bước phân tích trên ta có chương trình tính phần tử thứ n của dãy Fibonacci theo phuong phap quy hoach dong như sau:
Trang 37Function F(n: integer): integer;
var i: integer; a: array[1 100] of integer; Begin a[1]:=1: a[2]:=1: For 1:=3 ton do a[i]:=a[i-1]+a[i-2]; F:= a[n]; End;
2.3.1 Bài tốn cái túi xách (khơng bị chặn)
- Một cái kho chứa n loại đổ vật có kích thước và giá trị khác nhau Cụ thể:
Loại đồ vật ¡ (=1 n) có: - kích cỡ m{[i] eN*
BS?
- giá trị c[I| e R ae
- số lượng: không hạn chế
mỡ
Một tên trộm mang theo chiếc túi có kích cỡ là p e
N* Vậy hắn phải chọn lựa một danh sách các dé vat sé
mang đi như thế nào dé cho tổng giá trị lấy cắp được là lớn nhất
- Dữ liệu vào: Cho File CATTUIINP
Dòng đầu tiên cho biết số lượng đồ vật có trong kho và kích cỡ của túi Các dòng tiếp theo cho biết khối lượng của loại đồ vật m{ï] và giá trị c[ï]
- Dữ liệu ra: file CATTUI.OƯT
Trang 38CAITUI.INP CAITUI.OUT 4 37 83 15 30 23 10 25 41 22 31 46
2.3.1.1 Thuật toán giải bằng phương pháp đệ quy nhánh cận (u1, ., Un) |> f(u, ,un) = VE, ujyy;; (ui, .,un) ¢ D
Dat: D= {u = (uy, ,U, JEN": 3S ?—¡ u;W; < m}
va f:D>R*
Bài toán chiếc túi xách chuyển về bài toán sau: Tim x* eD: f* = f(x*) = {ƒ(u): ueD}
Cho nên ta sẽ kết hợp đánh giá nhánh cận trong quá trình liệt kê các lời giải theo phương pháp quay lui
Mô hình ban đầu có thể sử dụng như sau: Try @) For (j=1> 1) If (Chap nhan dugc ) then Begin Xác định xị theo J;
Ghi nhận trạng thái mới;
Trang 39Trả lại trạng thái cũ cho bài toán;
End;
* Cách chọn vật:
Xét mang don gia: Dg = et " =) Ta chọn vật theo đơn giá giảm dân
Không mất tính tổng quát, ta giả sử các loại vật cho theo thứ tự giảm dần của đơn giá
* Đánh giá cận trên:
Giả sử đã tìm được lời giải bộ phan: (x1, , xi)
S= View %jU; = Š + XjUj Khi đó:
- Giá trị của túi xách thu được:
- Tương ứng với trọng lượng các vật đã được xếp vào túi:
m = TU = m- 3j~¡ */W/ TL= Xj~¡/W;
- Do đó giới hạn trọng lượng của chiếc túi còn lại là:
Ta thấy đây là 1 bài tìm max Danh sách các đồ vật được sắp xếp theo thứ tự giảm của đơn giá đề xét phân nhánh
1 Nút gốc biểu diễn cho trạng thái ban đầu của túi xách, ở đó chưa chọn một
vật nào Tổng gia tri (TGT) duoc chon TGT = 0 Cận trên của nút gốc CT = W* Đơn giá lớn nhất
2 Nút gốc sẽ có các nút con tương ứng với các khả năng chọn đồ vật có đơn giá lớn nhất Với mỗi nút ta tính lại các thơng số:
Trang 40W=VW(cđ)— số đồ vật được chọn * trọng lượng mỗi vật
CT =TGT + W(mới) * đơn giá của vật sẽ xét kế tiếp
3 Trong các nút con, ta sẽ ưu tiên phân nhánh cho nút con nào có cận trên lớn hơn trước Các con của nút này tương ứng với các khả năng chọn đồ vật có đơn giá
lớn tiếp theo Với mỗi nút ta lại phải xác định lại các thông số TGT, W, CT theo công
thức đã nói trong bước 2
4 Lặp lại bước 3 với chú ý: đối với những nút có cận trên nhỏ hơn hoặc bằng giá lớn nhất tạm thời của một phương án đã được tìm thấy thì ta không cần phân nhánh cho nút đó nữa
5 Nếu tất cả các nút đều đã được phân nhánh hoặc bị cắt bỏ thì phương án có giá lớn nhất là phương án cần tìm
Ví dụ Với bài toán túi xách đã cho, sau khi tính đơn giá cho đồ vật và sắp xếp các đồ vật theo thứ tự giảm dần của đơn giá ta được bảng sau: Loại đồ vật ‹ Trọng lượng Giá trị Đơn giá (vị trí ban đâu) 2 10 25 2.5 1 15 30 2.0 4 4 6 1.5 3 2 2 1.0
Goi x1, x2, x3, x4 là số lượng cần chọn tương ứng của các đỗ vật thứ 2, 1, 4, 3 Nút gốc A biểu diễn cho trạng thái ta chưa chọn bất cứ một đồ vật nào Khi đó tổng gia tri TGT=0, trọng lượng của ba lô W=37 ( theo đề ra) và cận trên = 37*2.5 = 92.5,
trong đó 37 là W, 2.5 là đơn giá của đồ vật thứ 2
Với đồ vật thứ 2 ta có 4 khả năng chọn: Chọn 3 đồ vật thứ 2 (X1=3), chon 2 đồ
vật thứ 2 @X1=2), chon 1 dé vat thứ 2 ( XI=1) và không chọn đồ vật thứ 2 (X1=0) Ứng với bốn khả năng này, ta phân nhánh cho nút gốc A thành 4 con B, C, D và E