Your SlideShare is downloading. ×
0
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Quy hoạch động
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Quy hoạch động

18,221

Published on

Published in: Education, Sports
7 Comments
4 Likes
Statistics
Notes
No Downloads
Views
Total Views
18,221
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1,031
Comments
7
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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. 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. <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. <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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. <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>

×