Professional Documents
Culture Documents
Chap2 PDF
Chap2 PDF
1. Duyệt toàn bộ
2. Thuật toán quay lui
3. Thuật toán nhánh cận
1. Duyệt toàn bộ
2. Thuật toán quay lui
3. Thuật toán nhánh cận
Ví dụ:
Giá stock trong 6 ngày là {100, 60, 70, 65, 80, 85}, khi đó span = {1,1,2,1,4,5}.
Giải bằng phương pháp duyệt toàn bộ:
Duyệt lần lượt từng ngày i (từ trái sang phải for i = 0,..,5):
• span[i] = 1;
• quét lần lượt các ngày j trước nó (for j = i-1,..,0):
– if price[j] <= price[i] then span[i]++;
– else break;
Chú ý: Phân tích thời gian khấu trừ (amortized time analysis) không phải là
phân tích thời gian tính trung bình (average case analysis) vì phân tích thời
gian khấu trừ không đưa ra bất kỳ giả thiết nào về tính phân phối của giá trị
dữ liệu đầu vào như khi phân tích thời gian tính trung bình.
Câu hỏi:
• Mỗi khi biến đếm tăng thêm 1, ta sẽ phải làm gì ?
• Giả sử cần thực hiện liên tiếp n lần thao tác tăng biến đếm lên 1, khi đó
thời gian tính của dãy n thao tác này là bao nhiêu ?
Mảng đầy, cần tăng kích thước mảng lên gấp đôi:
m phần tử
1 2 3 4 14
Ví dụ 2: Growing an array
Amortized time: Phân tích thời gian khấu trừ
Chi phí
chèn n phần tử vào mảng (n=32): mỗi lần chèn 1 phần tử
)
15
Ví dụ 2: Growing an array
Amortized time: Phân tích thời gian khấu trừ
Chi phí chèn n phần tử vào mảng (n=32): mỗi lần chèn 1 phần tử
• Tổng chi phí thao tác nhanh:
– Mỗi thao tác: O(1) ⇒ 𝑐ℎ𝑖 𝑝ℎí 𝑐á𝑐 𝑡ℎ𝑎𝑜 𝑡á𝑐 𝒏𝒉𝒂𝒏𝒉 = 𝑂(𝑛)
– Có khoảng gần n thao tác
16
Ví dụ 2: Growing an array
Amortized time: Phân tích thời gian khấu trừ
Chi phí chèn n phần tử vào mảng (n=32): mỗi lần chèn 1 phần tử vào mảng
• Tổng chi phí thao tác chậm (nếu tính kích thước mảng khởi tạo ban đầu = 1):
– Khi mảng có 1 phần tử: tổng chi phí thao tác chậm = 1
– Khi mảng có 2 phần tử: tổng chi phí thao tác chậm = 1+ 2 = 3
– Khi mảng có 4 phần tử: tổng chi phí thao tác chậm = 3 + 4 = 7
– Khi mảng có 8 phần tử: tổng chi phí thao tác chậm = 7 + 8 = 15
– Khi mảng có 16 phần tử: tổng chi phí thao tác chậm = 15 + 16 = 31
– Khi mảng có 32 phần tử: tổng chi phí thao tác chậm = 31 + 32 = 63
= 63 nếu n = 32
17
Ví dụ 2: Growing an array
Amortized time: Phân tích thời gian khấu trừ
Chi phí chèn n phần tử vào mảng (n=32): mỗi lần chèn 1 phần tử vào mảng
• Tổng chi phí thao tác chậm (nếu tính kích thước mảng khởi tạo ban đầu = 1):
– Khi mảng có 1 phần tử: tổng chi phí thao tác chậm = 1
– Khi mảng có 2 phần tử: tổng chi phí thao tác chậm = 1+ 2 = 3 < 2 *2
– Khi mảng có 4 phần tử: tổng chi phí thao tác chậm = 3 + 4 = 7 < 2 * 4
– Khi mảng có 8 phần tử: tổng chi phí thao tác chậm = 7 + 8 = 15 < 2 * 8
– Khi mảng có 16 phần tử: tổng chi phí thao tác chậm = 15 + 16 = 31 < 2 * 16
– Khi mảng có 32 phần tử: tổng chi phí thao tác chậm = 31 + 32 = 63 < 2 * 32
< 2 * tổng số thao tác = 2n
18
Ví dụ 2: Growing an array
Amortized time: Phân tích thời gian khấu trừ
Chi phí
chèn n phần tử vào mảng (n=32): mỗi lần chèn 1 phần tử
=O(n+n) = O(n)
)
Xảy ra time limit exceeded khi kích thước dữ liệu đầu vào lớn
Cải tiến: O(rlogr) hoặc O(r) ???
NGUYỄN KHÁNH PHƯƠNG 22
Bộ môn KHMT – ĐHBK HN
Bài tập: Vito’s family
Giả sử có tập S chứa các số thực. Tìm phần tử sao cho ∈ đạt giá trị min.
Trả lời: khi x = phần tử trung vị của tập S (median of S).
1. Duyệt toàn bộ
2. Thuật toán quay lui
3. Thuật toán nhánh cận
26
2. Thuật toán quay lui
2.1. Sơ đồ thuật toán quay lui
2.2. Một số ví dụ minh họa
27
2.1. Sơ đồ thuật toán quay lui
• Bài toán liệt kê (Q): Cho A1, A2,..., An là các tập hữu hạn. Ký hiệu
A = A1 A2 ... An = { (a1, a2, ..., an): ai Ai , i=1, 2, ..., n}.
Giả sử P là tính chất cho trên A. Vấn đề đặt ra là liệt kê tất cả các
phần tử của A thoả mãn tính chất P:
D = { a = (a1, a2, ..., an) A: a thoả mãn tính chất P }.
• Các phần tử của tập D được gọi là các lời giải chấp nhận được.
(a1)
Tập UCV S2 khi đã có (a1)
a2
(a1, a2)
Tập UCV S3
khi đã có (a1, a2)
(a1, a2, a3)
a3
Tập UCV S4
khi đã có (a1, a2 , a3)
a4 a’4
Thuật toán quay lui (đệ qui) Thuật toán quay lui (không đệ qui)
38
3.2. Một số ví dụ minh họa
1. Liệt kê xâu nhị phân độ dài n
2. Liệt kê các m-tập con của n-tập
3. Liệt kê hoán vị
4. Bài toán xếp hậu
5. Bài toán tìm nghiệm nguyên
39
3.2. Một số ví dụ minh họa
1. Liệt kê xâu nhị phân độ dài n
2. Liệt kê các m-tập con của n-tập
3. Liệt kê hoán vị
4. Bài toán xếp hậu
5. Bài toán tìm nghiệm nguyên
40
Ví dụ 1: LiÖt kª x©u nhÞ ph©n ®é dµi n
• Bài toán liệt kê xâu nhị phân độ dài n dẫn về việc liệt kê các phần tử
của tập
Bn = {(b1, ..., bn): bi {0, 1}, i=1, 2, ..., n}.
• Ta xét cách giải quyết hai vấn đề cơ bản để cài đặt thuật toán quay lui:
– Xây dựng tập ứng cử viên Sk: Rõ ràng ta có S1 = {0, 1}. Giả sử đã
có xâu nhị phân cấp k-1 (b1, ..., bk-1), khi đó rõ ràng Sk = {0,1}.
Như vậy, tập các UCV vào các vị trí của lời giải đã được xác định.
– Cài đặt vòng lặp liệt kê các phần tử của Sk: ta có thể sử dụng vòng
lặp for
for (y=0;y<=1;y++)
()
Sk = {0,1}
0 1
(0)
(1)
0 1 0 1
(00) (01) (10) (11)
0 1 0 1 0 1 0 1
int main() {
cout<<"Nhap n = ";cin>>n;
count = 0; Xau();
cout<<"So luong xau = "<<count<<endl;
46
Ví dụ 2. Liệt kê các m-tập con của n-tập
Bài toán: Liệt kê các tập con m phần tử của tập N = {1, 2, ..., n}.
MSet(1); ()
1 3
2
(1,2,3) (1,2,4) (1,2,5) (1,3,4) (1,3,5) (1,4,5) (2,3,4) (2,3,5) (2,4,5) (3,4,5)
52
Ví dụ 3. Liệt kê hoán vị
TËp c¸c ho¸n vÞ cña c¸c sè tù nhiªn 1, 2, ..., n lµ tËp:
n = {(x1,..., xn) Nn: xi ≠ xj , i ≠ j }.
60
Ví dụ 4. Bài toán xếp hậu
• Liệt kê tất cả các cách xếp n quân Hậu trên bàn cờ nn sao
cho chúng không ăn được lẫn nhau, nghĩa là sao cho không
có hai con nào trong số chúng nằm trên cùng một dòng hay
một cột hay một đường chéo của bàn cờ.
n cột
The n-Queens Problem
– Chú ý: không phải hoán vị nào cũng là lời giải của bài toán xếp hậu:
7
|i1-i2| ≠ |j1-j2|
6
1 2 3 4 5 6 7 8
Bài toán xếp hậu: Thuật toán quay lui
Thuật toán: Xếp từng quân hậu lên lần lượt từng dòng của bàn cờ: tại bước lặp thứ
k (k=1,..,n): ta cần tìm tọa độ cột ak để đặt quân cờ lên dòng k [tức là đặt lên ô
(dòng k, cột ak)]
• Giả sử đã xây dựng được lời giải bộ phận (a1, a2, …, ak-1): tức là đã xếp được
(k-1) quân hậu lần lượt vào các ô (1, a1), (2, a2), …(k-1, ak-1) thỏa mãn điều kiện
đề bài.
• Giờ tiếp tục xây dựng thành phần thứ k của lời giải: tức là cần tìm tọa độ cột để
xếp quân hậu lên dòng thứ k của bàn cờ. Ta tiến hành như sau:
– Duyệt lần lượt từng cột j =1,2,..,n:
• Kiểm tra xem có thể xếp quân hậu lên ô (k, j) - dòng k cột j hay không:
bằng cách dùng hàm nhận biết ứng cử viên
UCVh(int j, int k) trả về giá trị 1 nếu xếp được; ngược lại hàm trả
về giá trị 0
UCVh nhận giá trị 1 khi và chỉ khi jSk
Thuật toán quay lui: Hàm nhận biết ứng cử viên
int UCVh(int j, int k) //check xếp quân hậu vào ô (k, j)
{ // UCVh nhận giá trị 1 khi và chỉ khi j Sk
for (i=1; i<k; i++) //duyệt qua lần lượt từ dòng 1..(k-1) là những dòng đã xếp quân hậu
if ((j == a[i]) || (fabs(j-a[i])== k-i)) return 0;
return 1;
}
void Try(int k) //tìm a[k]: cột xếp quân hậu thứ k lên dòng k
{
for (int j=1; j<=n; j++) //duyệt qua lần lượt từ cột 1..n: xem có xếp được lên ô (k, j) không
if (UCVh(j,k)) //nếu xếp được quân hậu lên ô (k, j)
{
a[k]=j;
if (k==n) Ghinhan(); //nếu đã xếp được đủ cả n quân hậu thì in ra lời giải
else Try(k+1); //nếu ko thì tiếp tục tìm vị trí xếp quân hậu thứ k+1 lên dòng thứ k+1
}
}
72
Chú ý
• Rõ ràng là bài toán xếp hậu không phải là luôn có lời giải,
chẳng hạn bài toán không có lời giải khi n = 2, 3. Do đó
điều này cần được thông báo khi kết thúc thuật toán.
Thuật toán làm việc như thế nào
Thuật toán làm việc như thế nào
ROW 1, COL 1
Thuật toán làm việc như thế nào
Xếp con hậu ở dòng 1
vào vị trí cột 1
ROW 1, COL 1
1 đã đặt
Thuật toán làm việc như thế nào
Thử xếp con hậu ở dòng 2
vào vị trí cột 1
ROW 2, COL 1
ROW 1, COL 1
1 đã đặt
Thuật toán làm việc như thế nào
Thử xếp con hậu ở dòng 2
vào vị trí cột 2
ROW 2, COL 2
ROW 1, COL 1
1 đã đặt
Thuật toán làm việc như thế nào
Thử xếp con hậu ở dòng 2
vào vị trí cột 3
ROW 2, COL 3
ROW 1, COL 1
1 đã đặt
Thuật toán làm việc như thế nào
Chấp nhận xếp con hậu ở dòng 2
vào vị trí cột 3
ROW 2, COL 3
ROW 1, COL 1
2 đã đặt
Thuật toán làm việc như thế nào
Thử xếp con hậu ở dòng 3
vào cột đầu tiên
ROW 3, COL 1
ROW 2, COL 3
ROW 1, COL 1
2 đã đặt
Thuật toán làm việc như thế nào
Thử cột tiếp theo
ROW 3, COL 2
ROW 2, COL 3
ROW 1, COL 1
2 đã đặt
Thuật toán làm việc như thế nào
Thử cột tiếp theo
ROW 3, COL 3
ROW 2, COL 3
ROW 1, COL 1
2 đã đặt
Thuật toán làm việc như thế nào
Thử cột tiếp theo
ROW 3, COL 4
ROW 2, COL 3
ROW 1, COL 1
2 đã đặt
Thuật toán làm việc như thế nào
...không có vị trí đặt
con hậu ở dòng 3.
ROW 3, COL 4
ROW 2, COL 3
ROW 1, COL 1
2 đã đặt
Thuật toán làm việc như thế nào
Quay lại dịch
chuyển con hậu ở
dòng 2
ROW 2, COL 3
ROW 1, COL 1
1 đã đặt
Thuật toán làm việc như thế nào
Đẩy con hậu ở dòng
2 sang cột thứ 4.
ROW 2, COL 4
ROW 1, COL 1
1 đã đặt
Thuật toán làm việc như thế nào
Xếp được con hậu ở
dòng 2 ta tiếp tục xếp
con hậu ở dòng 3
...
ROW 2, COL 4
ROW 1, COL 1
2 đã đặt
Mét lêi gi¶i cña bµi to¸n xÕp hËu khi n = 8
3.2. Một số ví dụ minh họa
1. Liệt kê xâu nhị phân độ dài n
2. Liệt kê các m-tập con của n-tập
3. Liệt kê hoán vị
4. Bài toán xếp hậu
5. Bài toán tìm nghiệm nguyên
90
Ví dụ 5. Bài toán nghiệm nguyên
Bài toán chia kẹo: Cần chia n cái kẹo cho k em bé B1, B2, …,Bk (có thể có
em bé không có cái kẹo nào). Hỏi có bao nhiêu cách chia khác nhau ?
Gọi xj là số kẹo chia cho em bé Bj, j=1,…,k. Khi đó, vấn đề đặt ra dẫn đến
bài toán:
Cho k và n là các số nguyên không âm. Hỏi phương trình sau đây có bao
nhiêu nghiệm nguyên không âm?
x1 x2 x3 xk n
x1 , x2 ,, x k 0
Số nghiệm nguyên không âm của phương trình là:
C(n+k-1, n) = C(n+k-1, k-1) = (n+k-1)! / n!(k-1)!
91
Bài toán chia kẹo
Khi chọn ra n đối tượng từ tập X, ta đặt chúng vào k hộp sao cho đối tượng loại
i sẽ được cho vào hộp i, 1 ≤ i ≤ k.
Vì đối tượng thuộc cùng 1 loại là giống nhau, ta dùng “0” kí hiệu cho các đối
tượng trong hộp, các đối tượng ở các hộp khác nhau được phân cách bởi vách
ngăn “1”.
Khi đó ta thu được dãy 0-1 độ dài n+(k-1) với đúng n số 0 và (k-1) số 1.
Ví dụ: k = 4, n = 7
4 loại đối tượng: a, b,c,d
Bài toán chuyển thành: đếm số dãy 0-1 độ dài n+k-1 với đúng n số 0 và (k-1) số 1
= C(n+k-1, n) = C(n+k-1, k-1) NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
92
Ví dụ 5. Bài toán nghiệm nguyên
Cho k và n là các số nguyên không âm. Hỏi phương trình sau đây có bao
nhiêu nghiệm nguyên không âm?
x1 x2 x3 x k n
x1 , x2 ,, xk 0
Số nghiệm nguyên không âm của phương trình là:
C(n+k-1, n) = C(n+k-1, k-1) = (n+k-1)! / n!(k-1)!
Cho k và n là các số nguyên không âm. Hỏi phương trình sau đây có bao nhiêu nghiệm
nguyên dương? x x x x n
1 2 3 k
x1 , x2 , , xk 0
Đặt yi = xi - 1 ≥ 0 y1 y2 y3 yk n k
y1 , y2 ,, yk 0
Số nghiệm nguyên dương của phương trình là: (n-1)!/(n-k)!(k-1)! 93
Ví dụ 5. Bài toán nghiệm nguyên
Cho k và n là các số nguyên không âm. Hỏi phương trình sau đây có bao
nhiêu nghiệm nguyên không âm?
x1 x2 x3 x k n
x1 , x2 ,, xk 0
Số nghiệm nguyên không âm của phương trình là:
C(n+k-1, n) = C(n+k-1, k-1) = (n+k-1)! / n!(k-1)!
Cho k và n là các số nguyên không âm. Hỏi phương trình sau đây có bao nhiêu nghiệm
nguyên dương? x x x x n
1 2 3 k
x1 , x2 , , xk 0
Đặt yi = xi - 1 ≥ 0 y1 y2 y3 yk n k
y1 , y2 ,, yk 0
Số nghiệm nguyên dương của phương trình là: (n-1)!/(n-k)!(k-1)! 94
Ví dụ 5. Bài toán nghiệm nguyên
Liệt kê tất cả các nghiệm nguyên dương của phương trình
x1 x2 x3 xk n
x1 , x2 , , xk 0
Thuật toán quay lui: Tìm giá trị cho từng biến xi của phương trình: tại bước lặp
thứ i (i=1,..,n): ta cần tìm giá trị của biến xi
• Giả sử đã xây dựng được lời giải bộ phận (x1, x2, …, xi-1): tức là đã biết được giá
trị của (i-1) biến đầu tiên lần lượt là x1, x2, …, xi-1
• Giờ tiếp tục xây dựng thành phần thứ i của lời giải: tức là cần tìm giá trị cho
biến xi. Ta tiến hành như sau:
– Tính tổng của (i-1) biến đầu tiên đã biết giá trị: M = x1 + x2+ …+xi-1
– Tổng (k-i) các biến từ xi+1, … ,xk ít nhất phải = k – i
– Giá trị lớn nhất mà xi có thể nhận: U = n – M – (k – i)
biến xi chỉ có thể nhận giá trị trong khoảng: 1 ≤ xi ≤ U
Thuật toán quay lui: Hàm nhận biết ứng cử viên
void UCV(int i) //tìm x[i]: giá trị cho biến xi
{
if (i==k) //chỉ còn biến cuối cùng xk cần xác định giá trị
{
U = n – M; L = U;
}
else
{
U = n – M – (n-i); L = 1;
}
for (j = L; j <= U; j++)
{
x[i] = j;
M = M + j;
if (i == k) Ghinhan();//nếu đã có được toàn bộ k giá trị biến xi thì in ra lời giải
else UCV(i+1);//tiếp tục xác định giá trị cho xi+1
M = M – j;
}
}
void nghiemnguyen(int k, int n)
{ M = 0; //lưu trữ tổng các biến đã xác định được giá trị
UCV(1);
}
Bài tập 1: The Hamming Distance problem
97
Bài tập 2: Optimal Slots
• https://codeforces.com/gym/102219/problem/E
98
Bài tập 2: Optimal Slots
• https://codeforces.com/gym/102219/problem/E
99
3. Thuật toán nhánh cận
3.1. Bài toán tối ưu tổ hợp
3.2. Một số ví dụ về bài toán tối ưu tổ hợp
3.3. Thuật toán nhánh cận (Branch and bound algorithm)
Ký hiÖu:
- tËp tÊt c¶ c¸c ho¸n vÞ cña n sè tù nhiªn 1, 2, ..., n.
Trong số các vectơ nhị phân độ dài n thỏa mãn điều kiện g(x) b, hãy
tìm vectơ x* cho giá trị lớn nhất của hàm mục tiêu f(x):
max { f(x): xBn, g(x) b }.
sign( x ) min,
j 1 i 1
ij
x
j 1
ij 1, i 1, 2,..., n
w x
i 1
i ij b, j 1, 2,..., n;
( ) D(a1,…,ak)
p
a1k 1 ak21 a
... k 1
Ta cã ph©n ho¹ch:
p
D(a1 ,..., ak ) D(a1 ,..., ak , aki 1 )
i 1
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Tính cận
• Cần có hàm g xác định trên tập tất cả các phương án bộ phận của bài toán thoả mãn
bất đẳng thức sau:
Giá trị hàm mục tiêu của mọi lời giải có k thành
phần đầu tiên là (a1, a2,…,ak)
với mỗi phương án bộ phận cấp k (a1, a2, ..., ak), và với mọi k = 1, 2, ...
• Bất đẳng thức (*) có nghĩa là giá trị của hàm g tại phương án bộ phận (a1, a2, ..., ak)
là không vượt quá giá trị nhỏ nhất của hàm mục tiêu của bài toán trên tập con các
phương án
hay nói một cách khác, g(a1, a2, . . . , ak) là cận dưới của giá trị hàm mục tiêu trên
tập D(a1, a2, ..., ak).
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Cắt nhánh nhờ sử dụng cận dưới
• Giả sử đã có hàm g. Ta xét cách sử dụng hàm này để giảm bớt
khối lượng duyệt trong quá trình duyệt tất cả các phương án theo
thuật toán quay lui.
• Trong quá trình liệt kê các phương án có thể đã thu được một số
phương án của bài toán. Gọi x* là phương án với giá trị hàm
mục tiêu nhỏ nhất trong số các phương án đã tìm được, ký hiệu
f* = f(x*)
• Ta sẽ gọi
• x* là phương án tốt nhất hiện có (phương án kỷ lục),
• f* là giá trị tốt nhất hiện có (giá trị kỷ lục).
a1
k 1 a 2
k 1 ... akq1
void BranchAndBound ( )
{
f* = +;
// Nếu biết p/án x* nào đó thì đặt f* = f(x*)
Try(1);
if (f* < +)
<f* là giá trị tối ưu, x* là p/án tối ưu >
else < bài toán không có phương án >;
}
ta còn phải đi qua n-k+1 đoạn đường nữa, mỗi đoạn có chi phí không ít hơn
cmin, nên cận dưới cho phương án bộ phận (1, u2, ..., uk) có thể tính theo công
thức:
g(1, u2, ..., uk) = + (n-k+1) cmin .
(2) (4);
(3); (5);
= 3 = 14 = 18 = 15
g = 3 + 4*3 = 15 g = 14 +4*3 = 26 g = 18 +4*3 = 30 g = 15 +4*3 = 27
(2,3,4); (2,3,5);
=7 +16 = 23 =7 +4 = 11
g = 23 + 2*3 = 29 g = 11 + 2*3 = 17
*
(2,3,4,5); (2,3,5,4);
=23 + 18 = 41 =11 + 5 = 16
0 3 14 18 15
* * 3 0 4 22 20
C= 17 9 0 16 4
9 20 7 0 18
9 15 11 5 0
Kết quả
Kết thúc thuật toán, ta thu được:
- phương án tối ưu (1, 2, 3, 5, 4, 1) tương ứng với hành trình
T1 T2 T3 T5 T4 T1 ,
- chi phí nhỏ nhất là 25.
j 1 j 1
j 1 j 1
c x (c / a ) a x
j 1
j j
j 1
1 1 j j
n
(c1 / a1 ) a j x j
j 1
(c1 / a1 )b g *
NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
n n
k max { c j x j : ax j j bk , x j 0, j k 1, k 2,..., n}
j k 1 j k 1
k ck 1bk / ak 1. Với trọng lượng còn lại bk: lấy toàn bộ là đồ vật (k+1) là đồ vật có giá trị nhất để
cho vào túi
• Vậy ta có thể tính cận trên cho phương án bộ phận (u1, u2, ..., uk) bởi công thức
g(u1, u2,..., uk) = k + ck+1 bk / ak+1. NGUYỄN KHÁNH PHƯƠNG
Bộ môn KHMT – ĐHBK HN
Tính cận trên
• Chú ý: Khi tiếp tục xây dựng thành phần thứ k+1 của lời
giải, các ứng cử viên cho xk+1 sẽ là 0, 1, ..., [bk / ak+1 ].
• Do có kết quả của mệnh đề, khi chọn giá trị cho xk+1 ta sẽ
duyệt các ứng cử viên theo thứ tự giảm dần
(1) = 10 (0); = 0
w = 8-5=3; g = 10 +5*3/3 = 15 w = 8; g = 0 +5*8/3 = 40/3
x2 = 1 Chọn đồ vật 2: x2 = 0
3/3 = 1
(1,1); = 10+5=15 (1,0); = 10+0=10
w = 3-3 = 0; g = 15 w = 3; g = 10+3*3/2=14.5
x3 = 0 Chọn đồ vật 3:
0/2 = 0
(1,1,0); = 15
w = 0; g = 15
• Kết
cácthúc
thànhthuật
phầntoán, ta thu án
của phương được:
bộ phận,
– -Phương áncác
giá trị của tốiđồ
ưu:
vậtx*đang
= (1, 1, trong
chất 0, 0),túi,
x4 = 0 Chọn đồ vật 4: – Giá trị tối ưu: f* = 15.
0/4 = 0 w – trọng lượng còn lại của túi,
g – cận trên của phương án bộ phận.
Ví dụ
Giải bài toán cái túi sau theo thuật toán nhánh cận
5x1 + 8x2 + x3 max
2x1 + 3x2 + x3 13
x1, x2, x3 0, nguyên
Chú ý: Trong ví dụ đang xét, các đồ vật chưa được sắp xếp theo thứ
tự không tăng của giá trị một đơn vị trọng lượng.
Thứ tự các đồ vật sắp xếp lại là: 2, 1, 3
x2 = 4 x2 = 0
x2 = 3 x2 = 2 x2 = 1
(4), = 8*4=32 (3); = 8*3=24 (1); = 8*1=8
(2); = 8*2=16 (0); = 0
w = 13-4*3=1; w = 13-3*3=4; w = 13-2*3=7; w = 13-1*3=10; w = 13;
g = 32 +5*1/3 =101/3 g = 24 +5*4/2 = 34 g = 16 +5*7/2 = 33,5 g = 8 +5*10/2 = 33 g = 0 +5*13/2 = 22,5
x1 = 0 x1 = 2 x1 = 0
x1 = 1
x3 = 1 x3 = 0 x3 = 0
(0,4,0); 𝑓 ̅ = 32
Gốc f* = +∞
xA = 1 xA = 3
xA =2 xA = 4
(A: job1);
g = 9 + 3 + 8 + 4 = 24
Xét tính cận dưới theo cách 1
Gốc f* = +∞
xA = 1 xA = 3
xA =2 xA = 4
(A: job1); f = 9 (A: job2); f = 2 (A: job3); f=7 (A: job4); f = 8
g = 9 + 3 + 8 + 4 = 24 g = 2 + 3 + 5 + 4 = 14 g = 7 + 4 + 5 + 4 = 20 g = 8 + 3 + 5 + 6 = 22
Gốc f* = +∞
xA = 1 xA = 3
xA =2 xA = 4
(A: job1); f=9 (A: job2); f=2 (A: job3); f=7 (A: job4); f=8
g = 9 + 3 + 8 + 4 = 24 g = 2 + 3 + 5 + 4 = 14 g = 7 + 4 + 5 + 4 = 20 g = 8 + 3 + 5 + 6 = 22
Loại vì g > f*
xB = 1 xB = 4 Loại vì g > f*
xB = 3
(A: job2, B:job1);f=8 (A: job2, B: job3);f=5 (A:job2, B: job4);f=9
g = 2 + 6 + 1 + 4 = 13 g = 2 + 3 + 5 + 4= 14 g = 2 + 7 + 1 + 7 = 17
Loại vì g > f* Loại vì g > f*
xC = 3 xC = 4
Kĩ thuật: Best First Search
(A: job2, B:job1, C:job3, D: job4) (A: job2, B:job1, C:job4, D: job3)
f = 2 + 6 + 1 + 4 = 13 f = 2 + 6 + 8+ 9 = 25
Loại vì f > f*
Dùng priority queue để lưu trữ
Thu được phương án của bài toán.
Cập nhật kỉ lục f* = 13
node trên cây
3.3.2.3. Bài toán giao việc (Assignment Problem)
170
3.3.2.3. Bài toán giao việc (Assignment Problem)
171
3.3.2.3. Bài toán giao việc (Assignment Problem)
172
3.3.2.3. Bài toán giao việc (Assignment Problem)
173
3.3.2.3. Bài toán giao việc (Assignment Problem)
174
3.3.2.3. Bài toán giao việc (Assignment Problem)
175
3.3.2.3. Bài toán giao việc (Assignment Problem)
176
Maze Solving Algorithm: findPath(x, y)