1 / 19

Áp dụng phương pháp quy hoạch động để giải các bài toán tối ưu trong tin học

Su1ef1 phu00e1t triu1ec3n nhu01b0 vu0169 bu00e3o cu1ee7a Cu00f4ng nghu1ec7 Thu00f4ng tin vu00e0 Truyu1ec1n thu00f4ng u0111u00f3ng vai tru00f2 khu00f4ng nhu1ecf trong su1ef1 phu00e1t triu1ec3n chung cu1ee7a nhu00e2n lou1ea1i. u0110u1ea3ng vu00e0 nhu00e0 nu01b0u1edbc u0111u00e3 xu00e1c u0111u1ecbnh ru00f5 u00fd nghu0129a vu00e0 tu1ea7m quan tru1ecdng cu1ee7a tin hu1ecdc, Cu00f4ng nghu1ec7 Thu00f4ng tin vu00e0 Truyu1ec1n thu00f4ng cu0169ng nhu01b0 yu00eau cu1ea7u u0111u1ea9y mu1ea1nh cu1ee7a u1ee9ng du1ee5ng Cu00f4ng nghu1ec7 Thu00f4ng tin, u0111u00e0o tu1ea1o thu1ebf hu1ec7 tru1ebb nu0103ng u0111u1ed9ng, su00e1ng tu1ea1o, nu1eafm vu1eefng tri thu1ee9c khoa hu1ecdc cu00f4ng nghu1ec7 u0111u1ec3 lu00e0m chu1ee7 trong mu1ecdi hou00e0n cu1ea3nh cu00f4ng tu00e1c vu00e0 hou1ea1t u0111u1ed9ng xu00e3 hu1ed9i trong thu1eddi ku1ef3 cu00f4ng nghiu1ec7p hu00f3a vu00e0 hiu1ec7n u0111u1ea1i hu00f3a u0111u1ea5t nu01b0u1edbc.

Download Presentation

Áp dụng phương pháp quy hoạch động để giải các bài toán tối ưu trong tin học

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên SỞ GIÁO DỤC VÀ ĐÀO TẠO LÀO CAI TRƯỜNG THPT CHUYÊN TỈNH LÀO CAI -----   ----- SÁNG KIẾN KINH NGHIỆM ỨNG DỤNG PHƯƠNG PHÁP QHĐ VÀO GIẢI QUYẾT MỘT SỐ BÀI TOÁN TRONG TIN HỌC HỌ TÊN GIÁO VIÊN: MAI HỒNG KIÊN Đơn vị: Tổ Toán - tin Năm học 2013 – 2014 1 https://sachhaynendoc.com.vn/

  2. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên MỤC LỤC Nội dung Trang 1 2 3 4 4 6 9 16 17 17 1 . Đặt vấn đề 2. Giải quyết vấn đề 2.1 Cơ sở lý luận 2.2 Thực trạng vấn đề 2.3 Các biện pháp thực hiện giải quyết vấn đề 2.3.1 Áp dụng phương pháp QHĐ 2.3.2 Ví dụ minh họa 2.3.3 Một số bài toán tối ưu giải bằng phương pháp QHĐ 2.4 Hiệu quả của SKNN 3 Kết luận 4. Tài liệu tham khảo 2 https://sachhaynendoc.com.vn/

  3. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên 1. Đặt vấn đề. - Sự phát triển như vũ bão của Công nghệ Thông tin và Truyền thông đóng vai trò không nhỏ trong sự phát triển chung của nhân loại. Đảng và nhà nước đã xác định rõ ý nghĩa và tầm quan trọng của tin học, Công nghệ Thông tin và Truyền thông cũng như yêu cầu đẩy mạnh của ứng dụng Công nghệ Thông tin, đào tạo thế hệ trẻ năng động, sáng tạo, nắm vững tri thức khoa học công nghệ để làm chủ trong mọi hoàn cảnh công tác và hoạt động xã hội trong thời kỳ công nghiệp hóa và hiện đại hóa đất nước. - Chính vì xác định được tầm quan trọng đó nên nhà nước đã đưa môn tin học vào trong nhà trường và ngay từ tiểu học học sinh được tiếp xúc môn tin học để làm quen dần với lĩnh vực công nghệ thông tin, tạo nền móng ban đầu để học những phần nâng cao tiếp theo. - Trong chương trình Tin học THPT lớp 10 học sinh được giới thiệu các kiến thức đại cương về tin học, lớp 11 học sinh được giới thiệu về lập trình, lớp 12 học sinh được học về cơ sở dữ liệu. Trong chương trình Tin học THPT thì chương trình lớp 11 là phần được cho là khó nhất, học sinh phải làm quen với ngôn ngữ lập trình Pascal và nắm được một số thuật toán. Chương trình tin học lớp 11 nhằm rèn luyện tư duy về thuật toán cho học sinh, rèn luyện kĩ năng lập trình, tính kiên trì, tỉ mỉ cẩn thận. - Tuy nhiên từ thực tiễn giảng dạyhọc sinh đại trà cũng như học sinh đội tuyển tin học củatrường THPT chuyên Lào Cai tôi thấy rằng, học sinh gặp khó khăn khi chuyển lời giải các bài toán từ toán sang ngôn ngữ lập trình.Đặc biệt là việc phân tích bài toán, nhận biết bài toán đó có thể giải quyết bằng phương pháp nào, cỏ lời giải tối ưu hay không ? Xuất phát từ cơ sở trên, tôi đã chọn đề tài “Áp dụng phương pháp quy hoạch động để giải các bài toán tối ưu trong tin học”, giúp các học sinh nắm được phương pháp quy hoạch động khi giải quyết những bài toán tối ưu trong tin học. 3 https://sachhaynendoc.com.vn/

  4. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên 2. Giải quyết vấn đề 2.1 .Cơ sở lí luận - Nguyên lý tối ưu của Bellman Phương pháp quy hoạch động cùng nguyên lý tối ưu được nhà toán học Mỹ R.Bellman đề xuất vào những năm 50 của thế kỷ 20. Phương pháp này đã được áp dụng để giải hàng loạt bài toán thực tế trong các quá trình kỹ thuật cộng nghệ, tổ chức sản xuất, kế hoạch hoá kinh tế… Trong thực tế, ta thường gặp một số bài toán tối ưu loại sau: Có một đại lượng f hình thành trong một quá trình gồm nhiều giai đoạn và ta chỉ quan tâm đến kết quả cuối cùng là giá trị của fphải lớn nhất hoặc nhỏ nhất, ta gọi chung là giá trị tối ưu của f. Giá trị của fphụ thuộc vào những đại lượng xuất hiện trong bài toán mà mỗi bộ giá trị của chúng được gọi là một trạng tháicủa hệ thống và phụ thuộc vào cách thức đạt được giá trị ftrong từng giai đoạn mà mỗi cách tổ chức được gọi là một điều khiển. Đại lượng f thường được gọi là hàm mục tiêuvà quá trình đạt được giá trị tối ưu của fđược gọi là quá trình điều khiển tối ưu. Bellman phát biểu nguyên lý tối ưu (cũng gọi là nguyên lý Bellman) mà ý tưởng cơ bản là như sau: “Với mỗi quá trình điều khiển tối ưu, đối với trạng thái bắt đầu A0, với trạng thái Atrong quá trình đó, phần quá trình kể từ trạng thái Axem như trạng thái bắt đầu cũng là tối ưu”. Chú ý rằng nguyên lý này được thừa nhận mà không chứng minh. Phương pháp tìm điều khiển tối ưu theo nguyên lý Bellman thường được gọi là quy hoạch động. Thuật ngữ này nói lên thực chất của quá trình điều khiển là động: có thể trong một số bước đầu tiên lựa chọn điều khiển tối ưu dường như không tốt nhưng tựu chung cả quá trình lại là tốt nhất. Hiểu một cách đơn giản hơn quy hoạch động làphương pháp giải bài toán từ nhỏ đến lớn, việc giải – tìm phương án tối ưu của các bài toán nhỏ vàlưu trữ các kết quả 4 https://sachhaynendoc.com.vn/

  5. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên này lại sẽ giúp ta có thể giải các bài toán với kích thước lớn dần đến khi đạt được kết quả mong muốn. 2.2 Thực trạng của vấn đề. Xét bài toán sau: Cho một dãy Nsố nguyên A1, A2,…,AN. Hãy tìm cách xoá đi một số ít nhất số hạng để dãy còn lại là đơn điệu hay nói cách khác hãy chọn một số nhiều nhất các số hạng sao cho dãy B gồm các số hạng đó theo trình tự xuất hiện trong dãy Alà đơn điệu. Quá trình chọn Bđược điều khiển qua N giai đoạnđể đạt được mục tiêu là số lượng số hạng của dãy Blà nhiều nhất, điều khiển ở giai đoạn i thể hiện việc chọn hay không chọn Ai vào dãy B. Giả sử dãy đã cho là 1 8 10 2 4 6 7. Nếu ta chọn lần lượt 1, 8, 10 thì chỉ chọn được 3 số hạng nhưng nếu bỏ qua 8 và 10 thì ta chọn được 5 số hạng 1, 2, 4, 6, 7. Khi giải một bài toán bằng cách “chia để trị” chuyển việc giải bài toán kích thước lớn về việc giải nhiều bài toán cùng kiểu có kích thước nhỏ hơn thì thuật toán này thường được thể hiện bằng các chương trình con đệ quy. Khi đó, trên thực tế, nhiều kết quả trung gian phải tính nhiều lần. Vậy ý tưởng cơ bản của quy hoạch động là : Tránh tính toán lại mọi thứ hai lần, mà lưu giữ kết quả đã tìm kiếm được vào một bảng làm giả thiết cho việc tìm kiếm những kết quả của trường hợp sau. Chúng ta sẽ làm đầy dần giá trị của bảng này bởi các kết quả của những trường hợp trước đã được giải. Kết quả cuối cùng chính là kết quả của bài toán cần giải. Nói cách khác phương pháp quy hoạch động đã thể hiện sức mạnh của nguyên lý chia để trị đến cao độ. Quy hoạch động là kỹ thuật thiết kế bottom-up (từ dưới lên). Nó được bắt đầu với những trường hợp con nhỏ nhất (thường là đơn giải nhất và giải được ngay). Bằng cách tổ hợp các kết quả đã có (không phải tính lại) của các trường hợp con, sẽ đạt đạt 5 https://sachhaynendoc.com.vn/

  6. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên tới kết quả của trường hợp có kích thước lớn dần lên và tổng quát hơn, cho đến khi cuối cùng đạt tới lời giải của trường hợp tổng quát nhất. Trong một số trường hợp, khi giải một bài toán A, trước hết ta tìm họ bài toán A(p) phụ thuộc tham số p (có thể p là một véc tơ) mà A(p0)=Avới p0là trạng thái ban đầu của bài toán A. Sau đó tìm cách giải họ bài toán A(p) với tham số p bằng cách áp dụng nguyên lý tối ưu của Bellman. Cuối cùng cho p=p0sẽ nhận được kết quả của bài toán Aban đầu. 2.3.Các biện pháp thực hiệngiải quyết vấn đề 2.3.1.Áp dụng phương pháp quy hoạch động. Bước 1: Lập hệ thức Dựa vào nguyên lý tối ưu tìm cách chia quá trình giải bài toán thành từng giai đoạn, sau đó tìm hệ thức biểu diễn tương quan quyết định của bước đang xử lý với các bước đã xử lý trước đó. Hoặc tìm cách phân rã bài toán thành các “bài toán con” tương tự có kích thước nhỏ hơn, tìm hệ thức nêu quan hệ giữa kết quả bài toán kích thước đã cho với kết quả của các “bài toán con” cùng kiểu có kích thước nhỏ hơn của nó nhằm xây dựng phương trình truy toán (dạng hàm hoặc thủ tục đệ quy). Về một cách xây dựng phương trình truy toán: Ta chia việc giải bài toán thành n giai đoạn. Mỗi giai đoạn i có trạng thái ban đầu là t(i) và chịu tác động điều khiển d(i) sẽ biến thành trạng thái tiếp theo t(i+1) của giai đoạn i+1 (i=1,2,…,n-1). Theo nguyên lý tối ưu của Bellman thì việc tối ưu giai đoạn cuối cùng không làm ảnh hưởng đến kết quả toàn bài toán. Với trạng thái ban đầu là t(n) sau khi làm giai đoạn n tốt nhất ta có trạng thái ban đầu của giai đoạn n-1 là t(n-1) và tác động điều khiển của giai đoạn n-1 là d(n-1), có thể tiếp tục xét đến giai đoạn n-1. Sau khi tối ưu giai đoạn n-1 ta lại có t(n-2) và d(n-2) và lại có thể tối ưu giai đoạn n-2 … cho đến khi các giai đoạn từ n giảm đến 1 được tối ưu thì coi như hoàn thành bài toán. Gọi giá trị tối ưu của bài toán tính đến giai đoạn k là Fk, giá trị tối ưu của bài toán tính riêng ở giai đoạn k là Gk thì 6 https://sachhaynendoc.com.vn/

  7. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên Fk = Fk-1 + Gk Hay là: = + − ( ( )) {G ( ( ), ( )) ( ( } )) 1 (*) F t k m ax k t k d k F t k − 1 k 1 k  ( ) d Bước 2: Tổ chức dữ liệu và chương trình Tổ chức dữ liệu sao cho đạt các yêu cầu sau: ▪ Dữ liệu được tính toán dần theo các bước. ▪ Dữ liệu được lưu trữ để giảm lượng tính toán lặp lại. ▪ Kích thước miền nhớ dành cho lưu trữ dữ liệu càng nhỏ càng tốt, kiểu dữ liệu được chọn phù hợp, nên chọn đơn giản dễ truy cập. Cụ thể •Các giá trị của Fkthường được lưu trữ trong một bảng (mảng một chiều hoặc hai, ba, v.v… chiều). •Cần lưu ý khởi trị các giá trị ban đầu của bảng cho thích hợp, đó là các kết quả của các bài toán con có kích cỡ nhỏ nhất của bài toán đang giải: = + ( 1 ( t )) {G ( 1 ( t ), 1 ( d )) ( 0 ( t )) } F m ax F 1 1 0 ) 1 ( d  •Dựa vào công thức, phương trình truy toán (*) và các giá trị đã có trong bảng để tìm dần các giá trị còn lại của bảng. •Ngoài ra còn cần mảng lưu trữ nghiệm tương ứng với các giá trị tối ưu trong từng gian đoạn. •Dựa vào bảng lưu trữ nghiệm và bảng giá trị tối ưu trong từng giai đoạn đã xây dựng, tìm ra kết quả bài toán. Bước 3: Làm tốt Làm tốt thuật toán bằng cách thu gọn hệ thức (*) và giảm kích thước miền nhớ. Thường tìm cách dùng mảng một chiều thay cho mảng hai chiều nếu giá trị một dòng (hoặc cột) của mảng hai chiều chỉ phụ thuộc một dòng (hoặc cột) kề trước. 7 https://sachhaynendoc.com.vn/

  8. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên Trong một số trường hợp có thể thay mảng hai chiều với các giá trị phần tử chỉ nhận giá trị 0, 1 bởi mảng hai chiều mới bằng cách dùng kỹ thuật quản lý bit. 2.3.2.Ví dụ minh họa Cho số tự nhiên n ≤ 100. Hãy cho biết có bao nhiêu cách phân tích số n thành tổng của dãy các số nguyên dương, các cách phân tích là hoán vị của nhau chỉ tính là một cách. n = 5 có 7 cách phân tích: 1.5 = 1 + 1 + 1 + 1 + 1 2.5 = 1 + 1 + 1 + 2 3.5 = 1 + 1 + 3 4.5 = 1 + 2 + 2 5.5 = 1 + 4 6.5 = 2 + 3 7.5 = 5 (Lưu ý: n = 0 vẫn coi là có 1 cách phân tích thành tổng các số nguyên dương (0 là tổng của dãy rỗng) Bước 1: Lập hệ thức Nhận xét: Nếu gọi F[m, v] là số cách phân tích số v thành tổng các số nguyên dương ≤ m. Khi đó: Các cách phân tích số v thành tổng các sốnguyên dương ≤ m có thể chia làm hai loại: - Loại 1: Không chứa sốm trong phép phân tích, khi đó số cách phân tích loại này chính là số cách phân tích số v thành tổng các sốnguyên dương < m, tức là số cách phân tích số v thành tổng các sốnguyên dương ≤ m - 1 và bằng F[m - 1, v]. - Loại 2: Có chứa ít nhất một sốm trong phép phân tích. Khi đó nếu trong các cách phân tích loại này ta bỏđi sốm đó thì ta sẽđược các cách phân tích số v - m thành tổng các sốnguyên dương ≤ m (Lưu ý: điều này chỉđúng khi không tính lặp lại các 8 https://sachhaynendoc.com.vn/

  9. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên hoán vị của một cách). Có nghĩa là về mặt sốlượng, số các cách phân tích loại này bằng F[m, v - m] Trong trường hợp m > v thì rõ ràng chỉ có các cách phân tích loại 1, còn trong trường hợp m ≤ v thì sẽ có cả các cách phân tích loại 1 và loại 2. Vì thế:    F[m 1, v]; if m > v F[m-1,v]+F[m,v-m]; if m F[m, v]=  v Bước 2: Tổ chức dữ liệu và chương trình Ta có công thức xây dựng F[m, v] từ F[m - 1, v] và F[m, v - m]. Công thức này có tên gọi là công thức truy hồi đưa việc tính F[m, v] về việc tính các F[m', v'] với dữ liệu nhỏhơn. Tất nhiên cuối cùng ta sẽquan tâm đến F[n, n]: Số các cách phân tích n thành tổng các sốnguyên dương ≤ n. Ví dụ với n = 5, bảng F sẽ là: F 0 1 2 3 4 5 V 0 1 0 0 0 0 0 1 1 1 1 1 1 1 2 1 1 2 2 3 3 3 1 1 2 3 4 5 4 1 1 2 3 5 6 5 1 1 2 3 5 7 m Nhìn vào bảng F, ta thấy rằng F[m, v] được tính bằng tổng của: Một phần tửở hàng trên: F[m - 1, v] và một phần tửở cùng hàng, bên trái: F[m, v - m]. Cài đặt: program Analysis_Counting; const max = 100; var F: array[0..max, 0..max] of Integer; n, m, v: Integer; 9 https://sachhaynendoc.com.vn/

  10. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên begin Write('n = '); ReadLn(n); FillChar(F[0], SizeOf(F[0]), 0); F[0, 0] := 1; for m := 1 to n do for v := 0 to n do if v < m then F[m, v] := F[m - 1, v] else F[m, v] := F[m - 1, v] + F[m, v - m]; WriteLn(F[n, n], ' Analyses'); end. Bước 3: Làm tốt Cải tiến dùng 2 mảng 1 chiều Cách làm trên có thể tóm tắt lại nhưsau: Khởi tạo dòng 0 của bảng, sau đó dùng dòng 0 tính dòng 1, dùng dòng 1 tính dòng 2 v.v… tới khi tính được hết dòng n. Có thể nhận thấy rằng khi đãtính xong dòng thứ k thì việc lưu trữ các dòng từ dòng 0 tới dòng k - 1 là không cần thiết bởi vì việc tính dòng k + 1 chỉ phụ thuộc các giá trị lưu trữ trên dòng k. Vậy ta có thể dùng hai mảng một chiều: Mảng Current lưu dòng hiện thời đang xét của bảng và mảng Next lưu dòng kế tiếp, đầu tiên mảng Current được gán các giá trị tương ứng trên dòng 0. Sau đódùng mảng Current tính mảng Next, mảng Next sau khi tính sẽ mang các giá trị tương ứng trên dòng 1. Rồi lại gán mảng Current := Next và tiếp tục dùng mảng Current tính mảng Next, mảng Next sẽ gồm các giá trị tương ứng trên dòng 2 v.v… Vậy ta có cài đặt cải tiến sau: program Analysis_Counting_2; const max = 100; var Current, Next: array[0..max] of Integer; n, m, v: Integer; begin Write('n = '); ReadLn(n); FillChar(Current, SizeOf(Current), 0); Current[0] := 1; for m := 1 to n do begin for v := 0 to n do if v < m then Next[v] := Current[v] 10 https://sachhaynendoc.com.vn/

  11. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên else Next[v] := Current[v] + Next[v - m]; Current := Next; end; WriteLn(Current[n], ' Analyses'); end. 2.3.3.Một số bài toán tối ưu giải bằng phương pháp quy hoạch động Bài toán 1: Bài toán cái túi Trong siêu thị có n gói hàng (n ≤ 100), gói hàng thứ i có trọng lượng là W[i] ≤ 100 và trị giá V[i] ≤ 100. Một tên trộm đột nhập vào siêu thị, tên trộm mang theo một cái túi có thểmang được tối đa trọng lượng M (M ≤ 100). Hỏi tên trộm sẽ lấy đi những gói hàng nào đểđược tổng giá trị lớn nhất. Input:file văn bản BAG.INP - Dòng 1: Chứa hai số n, M cách nhau ít nhất một dấu cách - n dòng tiếp theo, dòng thứ i chứa hai sốnguyên dương W[i], V[i] cách nhau ít nhất một dấu cách Output:file văn bản BAG.OUT - Dòng 1: Ghi giá trị lớn nhất tên trộm có thể lấy - Dòng 2: Ghi chỉ số những gói bị lấy BAG.INP BAG.OUT 5 11 11 3 3 5 2 1 4 4 5 4 9 10 4 4 11 https://sachhaynendoc.com.vn/

  12. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên Bài giải: Nếu gọi F[i, j] là giá trị lớn nhất có thể có bằng cách chọn trong các gói {1, 2, …, i} với giới hạn trọng lượng j. Thì giá trị lớn nhất khi được chọn trong số n gói với giới hạn trọng lượng M chính là F[n, M]. Công thức truy hồi tính F[i, j]. Với giới hạn trọng lượng j, việc chọn tối ưu trong sốcác gói {1, 2, …, i - 1, i} để có giá trị lớn nhất sẽ có hai khảnăng: oNếu không chọn gói thứ i thì F[i, j] là giá trị lớn nhất có thể bằng cách chọn trong sốcác gói {1, 2, …, i - 1} với giới hạn trọng lượng là j. Tức là F[i, j] = F[i - 1, j] oNếu có chọn gói thứ i (tất nhiên chỉ xét tới trường hợp này khi mà W[i] ≤ j) thì F[i, j] bằng giá trị gói thứ i là V[i] cộng với giá trị lớn nhất có thểcó được bằng cách chọn trong sốcác gói {1, 2, …, i - 1} với giới hạn trọng lượng j - W[i]. Tức là về mặt giá trịthu được: F[i, j] = V[i] + F[i - 1, j - W[i]] Vì theo cách xây dựng F[i, j] là giá trị lớn nhất có thể, nên F[i, j] sẽ là Max trong 2 giá trịthu được ở trên. Cơ sở quy hoạch động: Dễ thấy F[0, j] = giá trị lớn nhất có thể bằng cách chọn trong số 0 gói = 0. Tính bảng phương án: Bảng phương án F gồm n + 1 dòng, M + 1 cột, trước tiên được điền cơ sở quy hoạch động: Dòng 0 gồm toàn số 0. Sử dụng công thức truy hồi, dùng dòng 0 tính dòng 1, dùng dòng 1 tính dòng 2, v.v… đến khi tính hết dòng n. Truy vết Tính xong bảng phương án thì ta quan tâm đến F[n, M] đó chính là giá trị lớn nhất thu được khi chọn trong cả n gói với giới hạn trọng lượng M. Nếu F[n, M] = F[n - 1, M] thì tức là không chọn gói thứ n, ta truy tiếp F[n - 1, M]. Còn nếu F[n, M] ≠ F[n - 1, M] thì ta thông báo rằng phép chọn tối ưu có chọn gói thứ n và truy tiếp F[n - 1, M - W[n]]. Cứ tiếp tục cho tới khi truy lên tới hàng 0 của bảng phương án. program Bag; const 12 https://sachhaynendoc.com.vn/

  13. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên InputFile = 'BAG.INP'; OutputFile = 'BAG.OUT'; max = 100; var W, V: Array[1..max] of Integer; F: array[0..max, 0..max] of Integer; n, M: Integer; procedure Enter; var i: Integer; fi: Text; begin Assign(fi, InputFile); Reset(fi); ReadLn(fi, n, M); for i := 1 to n do ReadLn(fi, W[i], V[i]); Close(fi); end; procedure Optimize; var i, j: Integer; begin FillChar(F[0], SizeOf(F[0]), 0); for i := 1 to n do for j := 0 to M do begin {Tính F[i, j]} F[i, j] := F[i - 1, j]; if (j >= W[i]) and (F[i, j] < F[i - 1, j - W[i]] + V[i]) then F[i, j] := F[i - 1, j - W[i]] + V[i]; end; end; procedure Trace; var fo: Text; begin Assign(fo, OutputFile); Rewrite(fo); WriteLn(fo, F[n, M]); while n <> 0 do begin if F[n, M] <> F[n - 1, M] then begin Write(fo, n, ' '); M := M - W[n]; 13 https://sachhaynendoc.com.vn/

  14. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên end; Dec(n); end; Close(fo); end; begin Enter; Optimize; Trace; end. Bài toán 2: Chia thưởng Cần chia hết m phần thưởng cho n học sinh sắp theo thứ tự từ giỏi trở xuống sao cho mỗi bạn không nhận ít phần thưởng hơn bạn xếp sau mình. 1  m, n 70. Hãy tính số cách chia. Thí dụ, với số phần thưởng m= 7, và số học sinh n = 4 sẽ có 11 cách chia 7 phần thưởng cho 4 học sinh theo yêu cầu của đầu bài. Đó là: Phương án     1 7 2 6 3 5 4 5 5 4 6 4 7 3 8 3 9 4 10 3 11 2 0 1 2 1 3 2 3 2 1 2 2 0 0 0 1 0 1 1 2 1 1 2 0 0 0 0 0 0 0 0 1 1 1 14 https://sachhaynendoc.com.vn/

  15. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên Bài giải Lập hệ thức Gọi Chia(i, j) là số cách chia iphần thưởng cho j học sinh, tathấy: -Nếu không có học sinh nào (j = 0) thì không có cách chia nào (Chia = 0). -Nếu không có phần thưởng nào (i = 0) thì chỉ có một cách chia (Chia(0,j) = 1 - mỗi học sinh nhận 0 phần thưởng). Ta cũng quy ước Chia(0, 0) = 1. -Nếu số phần thưởng ít hơn số học sinh (i < j) thì trong mọi phương án chia, từ học sinh thứ i + 1 trở đi sẽ không được nhận phần thưởng nào: Chia(i, j) = Chia(i, i) nếu i < j. Ta xét tất cả các phương án chia trong trường hợp i j. Ta tách các phương án chia thành hai nhóm không giao nhau dựa trên số phần thưởng mà học sinh đứng cuối bảng thành tích, học sinh thứ j, được nhận: Nhóm thứ nhất gồm các phương án trong đó học sinh thứ jkhông được nhận - thưởng, tức là iphần thưởng chỉ chia cho j - 1 học sinhvà do đó, số cách chia, tức là số phần tử của nhóm này sẽ là: Chia(i, j - 1). Nhóm thứ hai gồm các phương án trong đó học sinh thứ j cũng được nhận - thưởng. Khi đó, do học sinh đứng cuối bảng thành tích được nhận thưởng thì mọi học sinh khác cũng sẽ có thưởng. Do ai cũng được thưởng nên ta bớt của mỗi người một phần thưởng (để họ lĩnh sau), số phần thưởng còn lại (i - j) sẽ được chia cho jhọc sinh. Số cách chia khi đó sẽ là Chia(i - j, j). Tổng số cách chia cho trường hợp i j sẽ là tổng số phần tử của hai nhóm, ta có: Chia(i, j) = Chia(i, j - 1) + Chia(i - j, j). Tổng hợp lại ta có: 15 https://sachhaynendoc.com.vn/

  16. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên Điều kiện i: số phần thưởng Chia(i, j) j: số học sinh j = 0 Chia(i, j) = 0 i = 0 and j  0 Chia(i, j) = 1 i < j Chia(i, j) = Chia(i, i) i  j Chia(i, j) = Chia(i, j – 1) + Chia(i – j, j) Các tính chất của hàm Chia(i, j) Chia i phần thưởng cho j học sinh Tổ chức dữ liệu và chương trình Ta có phương án đầu tiên của giải thuật Chia như sau: Phương án đệ quy. Hàm Chia(i,j) tính số cách chia i phần thưởng cho j học sinh function Chia(i,j: integer):longint; begin if j = 0 then Chia := 0 else {j > 0 } if i = 0 then {i = 0; j > 0 } Chia := 1 else {i,j > 0 } if i < j then {0 < i < j } Chia := Chia(i,i) else {i >= j > 0 } Chia := Chia(i,j-1)+Chia(i-j,j); end; Phương án này chạy chậm vì phát sinh ra quá nhiều lần gọi hàm trùng lặp. Bảng dưới đây liệt kê số lần gọi hàm Chia khi giải bài toán chia thưởng với bảy phần thưởng (m= 7) và 4 học sinh (n= 4). Thí dụ, hàm Chia(1,1) sẽ được gọi 9 lần,… Tổng số lần gọi hàm Chia là 79. 79 lần gọi hàm để sinh ra kết quả 11 là quá tốn kém. 16 https://sachhaynendoc.com.vn/

  17. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên         0 9   9 9   6 6   5 5   3 3   2 2   1 1   1 1 Số lần gọi hàm Chia cục bộ khi tính hàm Chia(7,4) 1 2 1 2 1 1 0 1 1 1 0 1 1 0 0 1 0 0 0 1 0 0 0 1 Làm tốt Phương án 1 khá dễ triển khai nhưng chương trình sẽ chạy rất lâu. Diễn tả đệ quy thường trong sáng, nhàn tản, nhưng khi thực hiện sẽ sinh ra hiện tượng gọi lặp lại những hàm đệ quy. Cải tiến là tránh những lần gọi lặpnhư vậy. Muốn thế chúng ta tính sẵn các giá trị của hàm theo các trị của đầu vào khác nhau và điền vào một mảng hai chiều cc. Mảng cc được mô tả như sau: const MN = 70;{ gioi han tren cua m va n } i - j ... i j - 1 j var cc: array[0..MN,0..MN] of longint; [i-j,j] ... Ta quy ước cc[i, j] chứa số cách chia i phần thưởng cho j [i,j-1] [i,j] học sinh. Theo phân tích của phương án 1, ta có: ⬧cc[0, 0] = 1; cc[i, 0] = 0, với i:=1..m. ⬧cc[i, j] = cc[i, i], nếu i < j ⬧cc[i, j] = cc[i, j-1]+cc[i-j, j], nếu ij. Từ đó ta suy ra quy trình điền trị vào bảng cc như sau: ⬧Khởi trị ⬧cc[0,0 ]:= 1; 17 https://sachhaynendoc.com.vn/

  18. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên ⬧với i := 1..m: cc[i,0] := 0; ⬧Điền bảng: Lần lượt điền theo từng cột j:= 1..n. Tại mỗi cột jta đặt: ⬧với i := 0..j-1: cc[i,j] := cc[i,i]; ⬧với i := j..m: cc[i,j] := cc[i,j-1]+cc[i-j,j]; Nhận kết quả: Sau khi điền bảng, giá trị cc[m, n] chính là kết quả cần tìm. Phương án dùng mảng 2 chiều: function Chia2(m,n: integer):longint; var i,j: integer; begin cc[0,0] := 1; for i := 1 to m do cc[i,0] := 0; for j := 1 to n do begin for i := 0 to j-1 do cc[i,j] := cc[i,i]; for i := j to m do cc[i,j] := cc[i,j-1]+cc[i-j,j]; end; Chia2 := cc[m,n]; end; 2.4.Hiệu quả của SKKN. - Trong quá trình trao đổi, thảo luận, trình bày học sinh được thể hiện khả năng vận dụng, hiểu biết của mình nên các em tỏ ra hăng hái trong việc giơ tay phát biểu tranh luận. - Đa số học sinh các lớp 11Toán, 11A1 nắm được “phương pháp quy hoạch động” và 100% học sinh đội tuyển nắm và vận dụng tốt kĩ thuật này. - Kết quả đạt được: Trong các năm học trước 2011-2012, 2012-2013 đội tuyển Tin học của trường không có giải HSGQG nào thì đến năm học 2013-2014 đội tuyển Tin học của trường đạt 8 giải HSG cấp tỉnh trong đó có giải nhất và giải nhì. 01 giải HSG Quốc gia. 18 https://sachhaynendoc.com.vn/

  19. Sáng kiến kinh nghiệm 2014 –Mai Hồng Kiên -THPT chuyên 3.Kết luận Như đã nói ở trên, chìa khóa trong thuật toán quy hoạch động là việc xây dựng các bài toán con mà ta gọi là mảng quy hoạch động. Mảng nàycó thể là 1, 2 hoặc có thể nhiều chiều tùy thuộc vào lời giải của bài toán phụ thuộc vào các loại tham số nào. Tiếp đến là cách quy nạp thu gọn bài toán sau mỗi bước, tức là không gian bài toán (kích thước dữ liệu) nhỏ lại, cho đến khi nào ta hoàn toàn có thể giải được bài toán nhỏ (điểm dừng của quy nạp). Bản chất của công việc này là ta phải xây dựng được lời giải của bài toán qua các bài toán con, tức là lập được công thức truy hồi, và dựa vào công thức truy hồi, ta sẽ biết được cần phải khởi tạo như thế nào. Trong các phần trên, chúng ta đã khảo sát một số bài toán có thể dùng thuật toán quy hoạch động để giải quyết một cách hiệu quả. Những vấn đề này đều liên quan đến bài toán tìm phương án tối ưuđể thực hiện một công việc nào đó và chúng có chung một tính chất là đáp án tốt nhất cho một bài toán con vẫn được duy trì khi bài toán con đó trở thành một phần trong bài toán lớn hơn. Thuật toán quy hoạch động thường được áp dụng để giải các bài toán tối ưu, bài toán đếm, …Vì vậy, nếu giới hạn kích thước dữ liệu của các bài toán tối ưu lớn và việc sử dụng các thuật toán khác (như duyệt, nhánh cận, ...) có độ phức tạp thời gian lớn thì chúng ta hãy nghĩ đến thuật toán quy hoạch động. TÀI LIỆU THAM KHẢO 1.Sách giáo khoa tin học 11 2. Sách giáo viên tin học 11 3. Tài liệu giáo khoa chuyên tin Hồ Sĩ Đàm Chủ biên Hồ Sĩ Đàm Chủ biên Hồ Sĩ Đàm Chủ biên 19 https://sachhaynendoc.com.vn/

More Related