QUY HOẠCH ĐỘNG1.Giới thiệu: Quy hoạch động là một phương pháp giảm thời gian chạy của các thuật toán thể hiện các tính chất củacác bài toán con gối nhau overlapping subproblem và cấu trú
Trang 1TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI TP HỒ CHÍ MINH
KHOA CÔNG NGHỆ THÔNG TIN
THUYẾT TRÌNH PHÂN TÍCH THIẾT KẾ GIẢI THUẬT
CHƯƠNG 3: PHÂN TÍCH ĐỘ PHỨC TẠP CỦA MỘT SỐ GIẢI THUẬT
TRÊN CẤU TRÚC DỮ LIỆU
Trang 2QUY HOẠCH ĐỘNG
1.Giới thiệu:
Quy hoạch động là một phương pháp giảm thời gian chạy của các thuật toán thể hiện các tính chất củacác bài toán con gối nhau (overlapping subproblem) và cấu trúc con tối ưu (optimal substructure).Cấu trúc con tối ưu có nghĩa là các lời giải tối ưu cho các bài toán con có thể được sử dụng để tìm cáclời giải tối ưu cho bài toán toàn cục Ví dụ, đường đi ngắn nhất tới một đỉnh trong một đồ thị có thểđược tìm thấy bằng cách: trước hết tính đường đi ngắn nhất tới đích từ tất cả các đỉnh kề nó, rồi dùngkết quả này để chọn đường đi toàn cục tốt nhất, như trong hình sau
Nói chung, ta có thể giải một bài toán với cấu trúc con tối ưu bằng một quy trình ba bước:
1 Chia bài toán thành các bài toán con nhỏ hơn
2 Giải các bài toán này một cách tối ưu bằng cách sử dụng đệ quy quy trình ba bước này
3 Sử dụng các kết quả tối ưu đó để xây dựng một lời giải tối ưu cho bài toán ban đầu
Các bài toán con được giải bằng cách chia chúng thành các bài toán nhỏ hơn, và cứ tiếp tục như thế,cho đến khi ta đến được trường hợp đơn giản dễ tìm lời giải
2.Quy hoạch động thường được áp dụng như sau:
• Quy động hoạch (dynamic programming) giải các bài toán bằng cách kết hợp các lời giải củacác bài toán con của bài toán đang xét
• Phương pháp này khả dụng khi các bài toán con không độc lập đối với nhau, tức là khi các bàitoán con có dung chung những bài toán “cháu” (subsubproblem)
• Quy hoạch động giải các bài toán cháu dung chung này một lần và lưu lời giải của chúng trongmột bảng và sau đó khỏi phải tính lại khi gặp bài toán đó
• Quy hoạch động thường được áp dụng cho những bài toán tối ưu hóa (optimization problem)
Trang 33.Quá trình xây dựng một giải thuật quy hoạch động: (Gồm 4 bước)
1 Đặc trưng hóa cấu trúc của lời giải tối ưu
2 Định nghĩa giá trị của lời giải tối ưu một cách đệ quy
3 Tính trị của lời giải tối ưu theo kiểu từ dưới lên
4 Cấu tạo lời giải tối ưu từ những thông tin đã được tính toán
Trang 4PHẦN I: NHÂN MA TRẬN
1 Giới thiệu về bài toán nhân ma trận:
Cho 2 ma trận A(p,q) và B(q,r) Khi nhân 2 ma trận thì độ phức tạp bằng số phép nhân 2 số (p*q*r).Phép nhân không có tính giao hoán nhưng có tính kết hợp
VD: A1*A *A 2 3 = A1*(A *A 2 3) = (A1*A )*A 2 3
Nên với phép nhân từ 3 ma trận trở lên thì với các cách kếp hợp khác nhau sẽ có độ phức tạp khácnhau
VD: A (10x100), A (100x5), A1 2 3(5x50)
A1*(A *A2 3) có 100x5x50 + 10x100x50 = 25000 + 50000 = 75000 phép nhân 2 số.(A *A )*A1 2 3 có 10x100x5 + 10x5x50 = 5000 + 2500 = 7500 phép nhân 2 số (giảm 10lần)
Mục tiêu của quy hoạch động trong bài toán nhân n ma trận là tìm ra cách kết hợp các phép nhânsao cho tổng số các phép nhân 2 số là nhỏ nhất (phép nhân vô hướng)
2 Độ phức tạp:
Nhân ma trận: Với ma trận AA kích thước (m×n)(m×n) và ma trận BB kích thước (n×p)(n×p) Độ
phức tạp của thuật toán để tính A×BA×B là O(m×n×p)O(m×n×p)
Ghi chú: Đối với phép nhân các ma trận vuông kích thước (n×n), có thuật toán nhân
ma trận Strassen với độ phức tạp O(nlog ) theo tư tưởng chia nhỏ ma trận (tương tự
2)≈O(n2.807cách nhân nhanh 2 số lớn) Tuy nhiên cài đặt rất phức tạp và trên thực tế với giá trị n thườnggặp, cách này không chạy nhanh hơn nhân ma trận thông thường O(n3)
Lũy thừa ma trận: Với ma trận vuông A cấp n, thuật toán tính A có độ phức tạp O(nk 3×log k)
3 Cách giải quyết bài toán theo phương pháp quy hoạch động:
Cho 1 dãy các ma trận A , A1 2,…,An, mỗi ma trận A có kích thước P x P i i-1 i
Đầu vào: dãy các kích thước P , P ,…, P 0 1 n
Đầu ra: dãy tích các ma trận A , A1 2,…,An kết hợp với nhau bởi dấu ngoặc sao cho tích các ma trận
có tổng số các phép tính vô hướng nhỏ nhất
Gọi A (i < j) là tích Ai…j i*Ai+1*…*Aj.
Ta có thể chia tích Ai*A *…*A i+1 j = (Ai*A *…*A )*(A i+1 k k+1*A *…*Aj)k+2
Tức là A = A * Ai…j i…k k+1…j
Có (j - i) cách chia như vậy (ứng với k = i,…, j -1)
Để tối ưu hoá tích A thì cả A và Ai…j i…k k+1…j cũng phải được tối ưu
Đặt m[i, j] là số nhỏ nhất các phép nhân 2 số để tính tích A
Trang 5Như vậy m[1, n] là số nhỏ nhất các phép nhân 2 số để tính tích A1…n.
Muốn cho m[1, n] nhỏ nhất thì các m[i, j] cũng phải nhỏ nhất
Vì A có thể tính bằng A * Ai…j i…k k+1…j, ta có công thức:
m[i, j] = 0, nếu i = j
m[i, j] = min {m[i, k] + m[k+1, j] + Pi-1*P *P k j}, với i <= k < j, nếu i < j
Để xác đinh điểm chia tối ưu k, ta sử dụng bảng s, trong đó s[i, j] = k (k là giá trị làm cho m[i,j] đạt min)
A1…A5: s[1, 5] = 4 => ((A1*A *A *A )*A )2 3 4 5
A1…A4: s[1, 4] = 2 => (((A1*A )*(A *A ))*A )2 3 4 5
A1…A2: s[1, 2] = 1 => (A1*A )2
A3…A4: s[3, 4] = 3 => (A3*A )
Trang 64 Code:
Tạo bảng:
Tra bảng:
Trang 7 Full code:
Trang 9Và đây là kết quả:
Trang 10PHẦN II : TÌM XÂU CON CHUNG DÀI NHẤT
1 Giới thiệu bài toán xâu con chung dài nhất (LCS – Longest common subsequence):
Bài toán xâu con chung dài nhất (lớn nhất) là một bài toán kinh điển cho việc ứng dụng thuật toán
quy hoạch động để giải quyết Chương này chúng ta đang tìm hiểu về Dynamic Programming Có thể
nói, đây là một bài toán rất hay giúp chúng ta hiểu cả về QHD, cả về cấu trúc ma trận mảng hai chiều
Bài toán được phát biểu như sau:
Viết chương trình nhập vào hai xâu kí tự, in ra độ dài xâu con chung lớn nhất và xâu chung đó củahai xâu vừa nhập
Ví dụ: hai xâu “BACDB” và “BDCB”, xâu con chung lớn nhất có độ dài là 3 và là “BCB”.
Như vậy có hai điểm cần chú ý trong bài toán này đó là:
2 Ý tưởng giải quyết bài toán:
2.1 Tìm độ dài xâu con lớn nhất:
Bài toán nhỏ nhất ở đây chính là việc so sánh các phần từ nằm trong xâu, nếu chúng bằng nhau thì
ta ghi nhận kết quả:
Công thứu quy hoạch động của bài toán xâu con chung lớn nhất:
Nếu A[i] == B[j] thì L[i][j] = L[i-1][j-1] + 1
Ngược lại thì L[i][j] = max (L[i-1][j], L[i][j-1])
Trong đó:
Trang 11 A, B là hai xâu cần xét
i, j tương ứng là chỉ số hàng và cột của mảng kết quả L
đầu tiên – L[i-1][j-1]
Để dễ hiểu hơn chúng ta hãy xem minh họa dưới đây:
Trang 12Công thức:
Nếu A [i] == B [j] : L [i] [j] == L [i-1] [j-1] + 1
Ngược lại : L [i] == max (L [i-1] [j], L [i] [j-1])
Xét hai xâu: BACDB và BDCB
Chú ý: độ dài hàng i trước, số cột j sau
Mảng lưu kết quả là một mảng hai chiều có kích thước L[n+1][m+1] trong đó n, m chính là độ dàicủa hai xâu a và b
Sở dĩ phải tăng thêm một đơn vị (n+1, m+1) để lưu thêm một hàng, cột có giá trị = 0 Tức là khichưa có phần tử nào thì số con chung sẽ là 0
Giá trị L[n][m] chính là độ dài của xâu con chung lớn nhất ta cần tìm
2.2 Truy vết xâu con chung:
Truy vết để tìm và in ra xâu con ra màn hình sẽ dựa vào bảng kết quả mà ta tìm được ở phần trên.Bắt đầu từ vị trí L[n][m] và dừng lại khi L[i][j] == 0
Bắt đầu duyệt từ i = n, j = m Phần tử thứ của xâu sẽ là i a a[i-1], thứ j của xâu sẽ là b b[j-1]
Nếu a[i-1] == b[j-1] ta sẽ lưu lại con chung a[i-1] và giảm i và j đi 1 đơn vị
Nếu a[i-1] != b[j-1] có 2 trường hợp:
- Nếu L[i-1][j] >= L[i][j-1] thì giảm 1 đơn vịi
- Ngược lại giảm đi 1 đơn vị j
Nếu thấy khó hiểu, bạn xem hình phía trên Màu green là trường hợp a[i-1] == b[j-1], màu blue làtrường hợp a[i-1] != b[j-1]
Trang 133 Phân tích độ phức tạp:
Khảo sát độ phức tạp trên số phép gán:
Gọi F(i,j) là LCS của hai tiền tố A1 i và B1 j
Khi đó ta có thể maximize F(i,j) theo F(i−1,j) và F(i,j−1)
Nếu Ai=Bj thì ta có thể cập nhật F(i,j) theo F(i−1,j−1)+1
Kết quả bài toán là F(m,n)
Vậy ta có độ phức tạp của bài tóan này theo phương pháp quy hoạch động là O(nm)
Trang 144 Code xâu con chung dài nhất C/C++:
Trang 15Và đây là kết quả chương trình trên:
Trang 16PHẦN III: BÀI TOÁN XẾP BALO
1.Giới thiệu về bài toán xếp balo:
Bài toán xếp ba lô (còn được biết đến với tên gọi bài toán cái túi) là một bài toán tối ưu hóa tổhợp Bài toán được đặt tên từ vấn đề chọn những gì quan trọng có thể nhét vừa vào trong một cái túi(với giới hạn khối lượng) để mang theo trong một chuyến đi Các bài toán tương tự thường xuất hiệntrong kinh doanh, toán tổ hợp, lý thuyết độ phức tạp tính toán, mật mã học và toán ứng dụng
2.Cách giải quyết bài toán bằng phương pháp quy hoạch động:
-Cho một cái balo có thể đựng một trọng lượng W và n loại đồ vật, mỗi đồ vật i có một trọng lượng
gi và một giá trị vi Tất cả các loại đồ vật đều có số lượng không hạn chế Tìm một cách lựa chọn các
đồ vật đựng vào balo, chọn các loại đồ vật nào, mỗi loại lấy bao nhiêu sao cho tổng trọng lượng khôngvượt quá W và tổng giá trị là lớn nhất
3.Xây dựng công thức truy hội để giải quyết bài toán:
và V là trọng lượng còn lại của balo, k=1 n, V=0 W
Ta có công thức truy hồi như sau:
trên
• Để lưu các giá trị trung gian trong quá trình tính F[k,V] và X[k,V] theo công thức truy hồi trên,
ta sử dụng một bảng gồm n dòng từ 1 đến n, dòng thứ k ứng với đồ vật loại k và W+1 cột từ 0đến W, cột thứ V ứng với trọng lượng V
• Mỗi cột V bao gồm hai cột nhỏ, cột bên trái lưu F[k,V], cột bên phải lưu X[k,V] Trong lập trình
ta sẽ tổ chức hai bảng tách rời là F và X
Ví dụ:
Cho bài toán balo với trọng lượng W=9, và 5 loại đồ vật được cho trong bảng sau:
Trang 1720
Chúng ta sẽ tra bảng đã được tính ở trên để xác định phương án:
X[k,V]>0 thì chọn X[k,v] đồ vật loại k tính lại V= V – X[k,V]*gk
Ví dụ, trong bảng trên, ta xét các đồ vật từ 5 đến 1 Khởi đầu V =W = 9
Với k = 5, vì X[5,9] = 0 nên ta không chọn đồ vật loại 5
Với k = 4, vì X[4,9] = 3 nên ta chọn 3 đồ vật loại 4 Tính lại V= 9 - 3*2=3
Với k = 3, vì X[3,3] = 0 nên ta không chọn đồ vật loại 3
Với k = 2, vì X[2,3] = 0 nên ta không chọn đồ vật loại 2
Với k = 1, vì X[1,3] = 1 nên ta chọn 1 đồ vật loại 1 Tính lại V = 3 – 1*3=0
Trang 18 Vậy tổng trọng lượng các vật được chọn là 3 * 2 + 1*3 = 9.
Tổng giá trị các vật được chọn là 3 * 3 + 1 * 4 = 13
Độ phức tạp của bài toán cái balo:
Gọi các chi phí là , , và các giá trị tương ứng là , , Ta cần cực đại hóa tổng giá trị vớic 1 c n v 1 v n
điều kiện tổng chi phí không vượt quá Khi đó, với mỗi ≤ , đặt C i C A(i) là giá trị lớn nhất có thể đạtđược với tổng chi phí không vượt quá Rõ ràng, i A(C) là đáp số của bài toán
Định nghĩa A(i) một cách đệ quy như sau:
A(0) = 0
A (i) = max { v j + (A i − c j), iA( ) | ≤ }cj i
Ở đây, giá trị lớn nhất của tập rỗng được lấy bằng 0 Tính dần các kết quả từ (0) tới A A(C), ta sẽđược lời giải Do việc tính mỗi A(i) đòi hỏi xem xét đồ vật (tất cả các giá trị này đã được tính từn
trước), và có giá trị của các C A(i) cần tính, nên thời gian chạy của lời giải quy hoạch động là O(nC).
Điều này không mâu thuẫn với thực tế rằng bài toán xếp ba lô là NP-đầy đủ, do , không như ,C n
không thuộc mức đa thức theo độ dài của đầu vào cho bài toán Độ dài đầu vào bài toán tỉ lệ thuận với
số bit trong , chứ không tỉ lệ với chính C C
Một giải pháp quy hoạch động tương tự cho bài toán xếp ba lô 0-1 cũng chạy trong thời giangiả-đa thức Cũng như trên, gọi các chi phí là , , và các giá trị tương ứng là , , Ta cần cực đạic 1 c n v 1 v n
hóa tổng giá trị với điều kiện tổng chi phí không vượt quá Định nghĩa một hàm đệ quy C A(i j, ) là giátrị lớn nhất có thể đạt được với chi phí không vượt quá và sử dụng các đồ vật trong khoảng từ tới j x1 x i
A(i,j) được định nghĩa đệ quy như sau:
f[i][j]:= giá trị lớn nhất có thể lấy được;
v[i]:= là giá trị của đồ vật thứ i;
w[i]:=trọng lượng của đồ vật thứ i
NOTES: Đây là bài toán không giới hạn đồ vật
Để có lời giải, ta tính A( , ) Để làm điều này, ta có thể dùng 1 bảng để lưu các tính toán trướcn C
đó Cách giải này do đó sẽ chạy trong thời gian O(nC) và không gian O(nC), tuy ta có thể giảm độphức tạp không gian xuống O( ) bằng một số sửa đổi nhỏ.C
Trang 19Code bài toán xếp balo:
Trang 21Kết quả chạy bài toán xếp balo cho ví dụ trên:
PHẦN IV: Đánh giá tổng quan về thuật toán quy hoạch động:
Quy hoạch động (Dynamic programming) là một kỹ thuật nhằm đơn giản hóa việc tính toán cáccông thức truy hồi bằng cách lưu trữ toàn bộ hay một phần kết quả tính toán tại mỗi bước với mục đích
Cách thứ hai đó là lưu trữ lại đáp án của các bài toán con (memoization), nhằm hạn chế việc tínhtoán Chúng ta sẽ có hai hướng tiếp cận chính, đó là từ trên xuống và từ dưới lên Từ trên xuống (top-down) là hướng tiếp cận mà chúng ta sẽ bắt đầu từ bài toán phức tạp Từ dưới lên (bottom-up) là hướngtiếp cận mà chúng ta sẽ giải các bài toán con cần thiết trước khi tiếp xúc với bài toán phức tạp