Quy hoạch động

5,687 views
5,491 views

Published on

Published in: Education, Sports
2 Comments
2 Likes
Statistics
Notes
No Downloads
Views
Total views
5,687
On SlideShare
0
From Embeds
0
Number of Embeds
235
Actions
Shares
0
Downloads
275
Comments
2
Likes
2
Embeds 0
No embeds

No notes for slide

Quy hoạch động

  1. 1. Chương III: Qui hoạch động (Dynamic Programming) <ul><li>Giới thiệu </li></ul><ul><li>Phương pháp thực hiện </li></ul><ul><li>Một số bài toán tối ưu giải bằng phương pháp quy hoạch động </li></ul>
  2. 2. 1. Giới thiệu <ul><li>Việc thực hiện một giải thuật đệ quy có thể không tối ưu về mặt thời gian/không gian nhớ. </li></ul><ul><li>Ví dụ: Tính phần tử thứ n của dãy số Fibonaci </li></ul><ul><li>Function F(n: integer): integer; </li></ul><ul><li>Begin If n  2 then F:=1 </li></ul><ul><li>else F:= F(n-1)+F(n-2); </li></ul><ul><li>End; </li></ul><ul><li>Độ phức tạp: O(a n ) với a  1.61803 ... </li></ul><ul><li>Do F(n-1) và F(n-2) được tính một cách độc lập! Số lần gọi cần để tính F(n) là số lần gọi để tính F(n-1) cộng với số lần gọi để tính F(n-2). </li></ul><ul><li>Đặc điểm của lời giải đệ quy: thực hiện bài toán từ việc phân tích ở mức cao xuống mức thấp. </li></ul>
  3. 3. <ul><li>Nếu giải quyết bài toán này từ mức thấp lên mức cao ta có giải thuật sau: </li></ul><ul><li>Function F(n: integer): integer; </li></ul><ul><li>var i: integer; a: array[1..100] of integer; </li></ul><ul><li>Begin </li></ul><ul><li>a[1]:=1; a[2]:=1; </li></ul><ul><li>For i:=3 to n do </li></ul><ul><li>a[i]:=a[i-1]+a[i-2]; </li></ul><ul><li>F:= a[i]; </li></ul><ul><li>End; </li></ul><ul><li>Độ phức tạp: O(n) </li></ul><ul><li>Đặc điểm của lời giải bài toán theo phương pháp quy hoạch động: giải quyết bài toán đệ quy từ mức thấp trước, lời giải của chúng được lưu lại và được sử dụng để tìm lời giải của các bài toán ở mức cao hơn. </li></ul>
  4. 4. <ul><li>Tư tưởng của phương pháp </li></ul><ul><ul><li>Sử dụng nguyên lý: “chia để trị” </li></ul></ul><ul><ul><li>Cách tiếp cận: “dưới-lên” </li></ul></ul><ul><li>Phạm vi áp dụng </li></ul><ul><ul><li>Các bài toán có được bằng việc tổ hợp các nghiệm của các bài toán con </li></ul></ul><ul><ul><li>Các bài toán tối ưu hoá rời rạc </li></ul></ul><ul><li>Nguyên lý của phương pháp: </li></ul><ul><ul><li>Nguyên lý tối ưu của Bellman: Trong một dãy tối ưu của các lựa chọn thì một dãy con của nó cũng là tối ưu. </li></ul></ul>
  5. 5. 2. Phương pháp thực hiện <ul><li>Phân tích bài toán (biểu diễn bài toán dưới dạng một bài toán nhiều mức) </li></ul><ul><li>Xây dựng giải pháp đệ quy (lập công thức truy hồi) </li></ul><ul><li>Lập bảng (sử dụng các mảng để tính toán các giá trị theo kiểu dưới-lên) </li></ul><ul><li>Tổng hợp kết quả (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) </li></ul>
  6. 6. Xét ví dụ trên <ul><li>Phân tích bài toán: Xây dựng hàm: </li></ul><ul><li>Function F(n: integer): integer; </li></ul><ul><li>Giải pháp đệ quy: F(n) = F(n-1)+F(n-2) </li></ul><ul><li>Lập bảng: Sử dụng mảng 1 chiều a (array[1..max] of integer) để tính: a[i] = F(i). với i = 1..n . </li></ul><ul><li>Cụ thể: </li></ul><ul><li>a[1] = a[2] = 1, và: </li></ul><ul><li>a[i] = a[i-1] + a[i-2]; với i = 3..n, </li></ul><ul><li>Tổng hợp kết quả: F(n) = a[n]; </li></ul><ul><li>Độ phức tạp tính toán: O(n) </li></ul>
  7. 7. Ví dụ tính C(k,n): tổ hợp chập k của n <ul><li>Phân tích bài toán: Xây dựng hàm: </li></ul><ul><li>Function C(k, n: byte): longint; {giả thiết k<=n} </li></ul><ul><li>Giải pháp đệ quy: C(k,n) = C(k-1,n-1) + C(k,n-1) </li></ul><ul><li>Lập bảng: Sử dụng một mảng 2 chiều a (array[0..max,0..max] of longint) để tính: </li></ul><ul><li>a[i,j] = C(i,j), với i = 0..k , j = i..n </li></ul><ul><li>Cụ thể: a[0,j] = 1,  j và a[i,i] = 1,  i </li></ul><ul><li>ngược lại: a[i,j] = a[i-1,j-1] + a[i,j-1] </li></ul><ul><li>Tổng hợp kết quả: C(k,n) = a[k,n] </li></ul><ul><li>Độ phức tạp tính toán: O(k.n) </li></ul>
  8. 8. 3. Một số bài toán tối ưu giải bằng phương pháp quy hoạch động <ul><li>Chiếc túi xách </li></ul><ul><li>Phép nhân tổ hợp nhiều ma trận </li></ul><ul><li>Các bài tập </li></ul>
  9. 9. Bài toán chiếc túi xách <ul><li>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ể: </li></ul><ul><li>Loại đồ vật i (i=1..n) có: - kích cỡ m[i]  N* </li></ul><ul><li>- gía trị c[i]  R </li></ul><ul><li>- số lượng: không hạn chế </li></ul><ul><li>Một tên trộm mang theo chiếc túi có kích cỡ là p  N*. Vậy hắn phải chọn lựa một danh sách các đồ vật sẽ mang đi như thế nào để cho tổng giá trị lấy cắp được là lớn nhất. </li></ul><ul><li>Tức: Tìm x[1], x[2],..., x[n] (với x[i]  N : số lượng loại đồ vật thứ i cần lấy) sao cho:  x[i].m[i]  p và  x[i].c[i] đạt giá trị cực đại </li></ul>
  10. 10. Bài toán chiếc túi xách <ul><li>Phân tích bài toán: </li></ul><ul><ul><li>Gọi P (r, s) là bài toán chiếc túi xách, với: </li></ul></ul><ul><ul><ul><li>r  N*: kích cỡ chiếc túi </li></ul></ul></ul><ul><ul><ul><li>s  N*: số các loại đồ vật khác nhau </li></ul></ul></ul><ul><ul><ul><li>(bài toán ban đầu là P (p, n) ) </li></ul></ul></ul><ul><ul><li>Các giá trị cần tìm: </li></ul></ul><ul><ul><ul><li>l[r,s]: giá trị cực đại  x[i].c[i] của bài toán P (r, s) </li></ul></ul></ul><ul><ul><ul><li>u[r,s]: số lượng loại đồ vật s tối ưu cần lấy (tức: x[s]) của bài toán P (r, s) </li></ul></ul></ul>
  11. 11. Bài toán chiếc túi xách P (r, s) <ul><li>Giải pháp đệ quy: </li></ul><ul><ul><li>Khi s = 1: </li></ul></ul><ul><ul><ul><li>u[r, 1] = r div m[1] </li></ul></ul></ul><ul><ul><ul><li>l[r, 1] = u[r, 1]  c[1] </li></ul></ul></ul><ul><ul><li>Khi s > 1: </li></ul></ul><ul><ul><ul><li>l[r, s] = max { k  c[s] + l[r – k  m[s], s-1] } </li></ul></ul></ul><ul><ul><ul><li> 0  k  r div m[s] </li></ul></ul></ul><ul><ul><ul><li>= k’  c[s] + l[r – k’  m[s], s-1] </li></ul></ul></ul><ul><ul><ul><li>u[r, s] = k’ </li></ul></ul></ul>
  12. 12. Lập bảng (Bài toán chiếc túi xách) <ul><li>Procedure LapBang; </li></ul><ul><li>Begin </li></ul><ul><ul><li>For r:=0 to p do </li></ul></ul><ul><ul><li>For s:=1 to n do </li></ul></ul><ul><ul><li>If s=1 then Tính u[r, 1] và l[r, 1] </li></ul></ul><ul><ul><li> else Tính u[r, s] và l[r, s]; </li></ul></ul><ul><li>End; </li></ul><ul><li>Độ phức tạp tính toán: O(np 2 ) </li></ul>
  13. 13. Tổng hợp kết quả (Bài toán chiếc túi xách) <ul><li>Procedure TongHop; </li></ul><ul><li>Begin </li></ul><ul><li>r:=p; </li></ul><ul><li>For s:=n downto 1 do </li></ul><ul><li>begin </li></ul><ul><li>x[s]:= u[r,s]; </li></ul><ul><li>r:= r – x[s].m[s]; </li></ul><ul><li>end; </li></ul><ul><li>End; </li></ul><ul><li>Độ phức tạp tính toán: O(n) </li></ul>
  14. 14. Bài toán Phép nhân tổ hợp nhiều ma trận <ul><li>Cần tính M = M 1  M 2  ...  M n </li></ul><ul><li>Trong đó: M i là ma trận cấp m[i-1]  m[i] (i=1..n) </li></ul><ul><li>Hãy xác định thứ tự thực hiện các phép nhân sao cho số phép tính là tối thiểu. </li></ul><ul><li>Ví dụ: Tính M = M 1  M 2  M 3 </li></ul><ul><li> [10  20] [20  50] [50  5] </li></ul><ul><li>( M 1  M 2 )  M 3 có số phép toán là: </li></ul><ul><li>10  20  50 + 1 0  50  5 = 12500 </li></ul><ul><li>M 1  ( M 2  M 3 ) có số phép toán là: </li></ul><ul><li>10  20  5 + 2 0  50  5 = 6000 </li></ul>
  15. 15. Phép nhân tổ hợp nhiều ma trận <ul><li>Phân tích bài toán: </li></ul><ul><ul><li>Gọi P (r, s) là bài toán nhân ma trận: M r  M r+1  ...  M s , với r  s </li></ul></ul><ul><ul><li>(bài toán ban đầu là P (1, n) ) </li></ul></ul><ul><ul><li>Giá trị cần tìm: </li></ul></ul><ul><ul><ul><li>k[r,s]: vị trí phép toán thực hiện cuối cùng của bài toán P (r, s) </li></ul></ul></ul><ul><ul><ul><li>(M r  M r+1  ...  M k-1 )  ( M k  M k+1  ...  M s ) </li></ul></ul></ul><ul><ul><ul><li> k = k[r,s]  [r+1, s] </li></ul></ul></ul><ul><ul><ul><li>l[r, s]: số phép tính nhân tối ưu của bài toán P (r, s) </li></ul></ul></ul>
  16. 16. Phép nhân tổ hợp nhiều ma trận <ul><li>Giải pháp đệ quy: </li></ul><ul><ul><li>Trường hợp 1: Khi s = r : l[r, r] = 0 </li></ul></ul><ul><ul><li>Trường hợp 2: Khi s = r+1: </li></ul></ul><ul><ul><ul><li>l[r, r+1] = m[r-1]  m[r]  m[r+1] </li></ul></ul></ul><ul><ul><ul><li>k[r, r+1] = r+1 </li></ul></ul></ul><ul><ul><li>Trường hợp 3: Khi s > r+1: </li></ul></ul><ul><ul><ul><li>l[r, s] = min { l[r, v-1] + m[r-1]  m[v-1]  m[s] + l[v, s] } </li></ul></ul></ul><ul><ul><ul><li>r+1  v  s </li></ul></ul></ul><ul><ul><li>(v là các vị trí phép toán thực hiện cuối cùng khác nhau) </li></ul></ul><ul><ul><ul><li>= l[r, v’-1 ] + m[r-1]  m[v’-1]  m[s] + l[v’, s] </li></ul></ul></ul><ul><ul><li>(v’ là vị trí tối ưu trong số các vị trí của v) </li></ul></ul><ul><ul><ul><li>k[r, s] = v’ </li></ul></ul></ul><ul><ul><li>Nhận xét : Có thể ghép trường hợp 2 vào trường hợp 3! </li></ul></ul>
  17. 17. Lập bảng (Bài toán phép nhân tổ hợp nhiều ma trận) <ul><li>Procedure LapBang; </li></ul><ul><li>Begin </li></ul><ul><ul><li>For s:=1 to n do </li></ul></ul><ul><ul><li>For r:=s downto 1 do </li></ul></ul><ul><ul><li>If r = s then l[r, r] := 0 </li></ul></ul><ul><ul><li> else Tính l[r, s] và k[r, s]; </li></ul></ul><ul><li>End; </li></ul><ul><li>Độ phức tạp tính toán: O(n 3 ) </li></ul>
  18. 18. Tổng hợp kết quả (Bài toán phép nhân tổ hợp nhiều ma trận) <ul><li>Procedure TongHop; </li></ul><ul><li>Begin </li></ul><ul><li>writeln(‘S ố phép tính là tối thiểu:’, l[1, n]); </li></ul><ul><li>i:=n; </li></ul><ul><li>TimVT(1, n); {Nhằm lần lượt xác định các giá trị x[i]: vị trí phép nhân cần thực hiện trong lần nhân thứ i (i=1..n-1)} </li></ul><ul><li>writeln(‘ Thứ tự thực hiện các phép nhân :’); </li></ul><ul><li>For i:=1 to n-1 do writeln(x[i]); </li></ul><ul><li>End; </li></ul><ul><li>Trong đó thủ tục TimVT được xây dựng đệ quy như sau: </li></ul><ul><li>Procedure TimVT(r, s); </li></ul><ul><li>Begin i:=i-1; vt:= k[r, s]; x[i]:= vt; </li></ul><ul><li>If (vt > r+1) and (vt < s) then </li></ul><ul><li>begin TimVT(r, vt-1); </li></ul><ul><li>TimVT(vt, s); </li></ul><ul><li>end; </li></ul><ul><li>End; </li></ul>
  19. 19. Bài tập <ul><li>1. Tính giá trị xác suất P(i, j) (i, j: byte). Biết rằng: </li></ul><ul><li>P(i, j) = 1 nếu i=0 và j>0 </li></ul><ul><li>= (P(i-1, j)+ P(i, j-1))/2 nếu i>0 và j>0 </li></ul><ul><li>= 0 nếu ngược lại </li></ul><ul><li>Bài toán xâu trong cực đại: S là xâu trong của T nếu S nhận được bằng cách xoá đi một số ký tự nào đó. Ví dụ: ‘ABC’ là xâu trong của ‘GAHEBOOC’ </li></ul><ul><li>Bài toán: Cho 2 xâu T1, T2. Tìm một xâu S là xâu trong chung của T1 và T2 có độ dài cực đại. </li></ul><ul><li>Ví dụ: T1=‘ABCDAE’ và T2=‘XYACADK’ có xâu ‘ACD’ là xâu trong chung với độ dài cực đại. </li></ul>
  20. 20. <ul><li>Bài toán du lịch: Một người đi từ thành phố 0 đến thành phố n và có thể đi qua n-1 thành phố khác 1, 2,..., n-1 , theo lộ trình : 0  i 1  i 2 …..  i k  n, t rong đó: 0 < i 1 < i 2 < …< i k < n, Giá vé của xe đi từ thành phố i đến thành phố j là c[i,j]. Tìm một lộ trình từ thành phố 0 đến thành phố n sao cho tổng chi phí về giá vé đạt cực tiểu. </li></ul><ul><li>Bài toán sinh viên ôn thi: Một sinh viên còn m ngày để ôn thi n môn. Theo kinh nghiệm của anh ta, nếu ôn môn j trong i ngày thì được điểm là a[i,j]. Giả sử cho biết các a[i,j] (với a[i,j]<=a[i+1,j]). </li></ul><ul><li>Tìm bộ x[j] (số ngày ôn môn j, với j=1..n) sao cho  x[j]=n và sinh viên đạt tổng điểm lớn nhất (  a[x[j], j]  max). </li></ul>

×