1. Giới thiệu bài toán
Chọn cấu hình tối ưu trong số các cấu hình thoả mãn các điều kiện cho trước gọi là bài toán tối ưu. Dạng tổng quát của bài toán như sau:
Tìm giá trị nhỏ nhất (hay lớn nhất) của hàm f(x); với x ∈D (D là tập hữu hạn)
Hàm f(x) gọi là hàm mục tiêu, mỗi phần tử x ∈ D gọi là một phương án (phương án chính là cấu
hình thoả mãn các điều kiện cho trước), tập D gọi là tập các phương án. Phương án x* ∈ D sao
cho f(x*) nhỏ nhất (hay lớn nhất) gọi là phương án tối ưu, khi đó giá trị f*=f(x*) gọi là giá trị tối ưu. 2. Một số bài toán tối ưu
2.1 Bài toán người du lịch
Một người du lịch xuất phát từ một thành phố, muốn đi qua n thành phố, mỗi tp một lần, rồi quay lại tp xuất phát. Biết mỗi chi phí từ tp này đến tp khác, tìm hành trình có tổng chi phí là nhỏ nhất. Gọi Ti là tp thứ i, Cij là chi phí đi từ Ti đến Tj. Mỗi hành trình có dạng: Tx1 --> Tx2 -->… -->Txn với x=(x1, x2,…, xn) là một hoán vị của tập {1,2,…,n}. Đặt f(x)=Cx1,x2 + Cx2,x3+…+ Cxn,x1 và gọi D là tập tất cả các hoán vị. Bài toán người du lịch có thể phát biểu ở dạng bài toán tối ưu như sau:
Tìm min { f(x) | x ∈D}.
NX: có (n-1)! hành trình cần phải xét. 2.2 Bài toán cái túi
Có n vật, vật thứ i có trọng lượng là ai và giá trị sử dụng là ci . Một nhà thám hiểm có một cái túi sức chứa tối đa là b. Hỏi nhà thám hiểm cần đem theo các vật nào để tổng giá trị sử dụng là lớn nhất?
Một phương án có dạng x=(x1, x2,…, xn) với xi=1 là đồ vật thứ i được đem theo và xi=0 là đồ vật thứ i không được đem theo. Với phương án x
giá trị đồ vật mang theo là f(x)= 1
n i i i c x = ∑ và
tổng trọng lượng đồ vật mang theo là g(x)= 1
n i i i a x = ∑
Gọi D là tập tất cả các chuỗi nhị phân độ dài n. Bài toán cái túi có thể phát biểu ở dạng bài toán tối ưu như sau:
Tìm max { f(x) |g(x)≤b, x ∈D}.
2.3 Bài toán cho thuê máy
Một ông chủ có một cái máy để cho thuê. Đầu tháng ông ta nhận được yêu cầu thuê máy của m khách hàng. Mỗi khách hàng i sẽ cho biết tập Ni các ngày trong tháng cần sử dụng máy. Ông chủ có quyền từ chối hoặc nếu nhận thì phải bố trí máy phục vụ khách hàng i đúng những ngày mà khách hàng này yêu cầu. Hỏi rằng ông chủ phải tiếp nhận các yêu cầu của khách như thế nào để cho tổng số ngày sử dụng máy là lớn nhất?
Gọi P={1,2,…,m} là tập chỉ số khách hàng. Khi đó tập các phương án cho thuê máy là:
F(K)= k k K N ∈ ∑ .
Bài toán cho thuê máy có thể phát biểu ở dạng bài toán tối ưu như sau: Tìm max { F(K) | K ∈D}.
2.4 Bài toán đóng thùng
Tìm cách xếp n vật, trọng lượng là w1,…,wn ≤ b vào các thùng có cùng dung lượng là b, sao cho số thùng sử dụng là ít nhất.
2.5 Bài toán phân công
Có n công việc và n thợ, mỗi thợ thực hiện 1 công việc và 1 công việc chỉ do 1 thợ thực hiện. Gọi Cij là chi phí cần trả để thợ i hoàn thành cv j. Hãy tìm cách thuê sao cho tổng chi phí thuê là nhỏ nhất.
Gọi P={1,2,…,m} là tập các chỉ số của thợ. Tập các phương án là: D={x=(x1,…,xn) : x là một hoán vị của P}. Chi phí với phương án x ∈D là: F(x)=Cx1,1+…+Cxn,n .
Bài toán phân công có thể phát biểu ở dạng bài toán tối ưu như sau: Tìm min { F(x) | x ∈D}.
3. Các thuật toán duyệt
3.1 Thuật toán duyệt toàn bộ
Dùng các thuật toán liệt kê, duyệt tất cả các phương án có thể xảy ra, tính giá trị hàm mục tiêu của mỗi phương án. So sánh các giá trị hàm mục tiêu để tìm ra phương án tối ưu.
Nếu số phương án là qúa nhiều thì thuật toán sẽ thực thi rất chậm, không thể chấp nhận được. Khi đó ta cần tận dụng những thông tin đã tìm được để loại bỏ bớt những phương án không tối ưu và dẫn đến thuật toán nhánh cận.
3.2 Thuật toán nhánh cận
3.2.1 Ý tưởng:
Sử dụng thuật toán quay lui và dùng hàm “cận dưới” g để loại bớt các phương án không thể là phương án tối ưu.
- Xét phương án x =(x1,…,xk,…xn) thì a=(a1,…,ak) với ai=xi, gọi là phương án bộ phận cấp k (k≤n). - G/s đã xây dựng được hàm g (hàm tính cận dưới) như sau: với mọi phương án bộ phận (a1, …,ak) và với mọi k=1,…,n
g(a1, …,ak) ≤ min {f(x): x ∈ D, x1 = a1, …,xk = ak}
Gọi x là phương án tốt nhất hiện có và f = f(x) gọi là kỷ lục hiện tại . Nếu phương án bộ phận a=(a1,…,ak) có g(a1, …,ak) > f
⇒ f < g(a
1, …,ak) ≤ min {f(x): x ∈ D, x1 = a1, …,xk = ak}
⇒các phương án hoàn chỉnh x=(x1,…,xn) phát triển từ phương án bộ phận a=(a1, …,ak) đều có hàm mục tiêu f(x) > kỷ lục f , nên ta loại tất cả các phương án hoàn chỉnh x phát triển từ phương án bộ phận a.
* Ghi chú:
Nếu bài toán tối ưu là tìm max {f(x): x ∈ D} thì cần xây dựng được hàm g (hàm tính cận trên) sao
cho:
g(a1, …,ak) ≥ max {f(x): x ∈ D, x1 = a1, …,xk = ak}
và nếu phương án bộ phận a=(a1,…,ak) có g(a1, …,ak) < f
⇒ f > g(a
⇒các phương án hoàn chỉnh x=(x1,…,xn) phát triển từ phương án bộ phận a=(a1, …,ak) đều có hàm mục tiêu f(x) < kỷ lục f , nên ta loại tất cả các phương án hoàn chỉnh x phát triển từ phương án bộ phận a.
3.2.2 Cài đặt: (tìm min)
void Try(int i) //xac dinh xi
{
for (xét tất cả các knj của xi) {
if (chấp nhận knj) //nếu chấp nhận khả năng j {
ghi nhận việc đã chọn knj // (*) :lệnh này có thể không có xi = knj; //lưu kn j vào xi
if (i==n) //đã xác định đủ n thành phần
cập nhật kỷ lục nếu kỷ lục mới nhỏ hơn; else
if ( g(a1, …,ak) ≤ f ) //tim max thi g(a
1, …,ak)≥ f
Try(i+1); // xác định xi+1
ghi nhận việc bỏ chọn knj // lệnh này không có nếu (*) không có }
} }
void nhanhcan() {
f = +∞; //nếu biết một phương án x nào đó thì có thể đặt f = f(x).Nếu tìm max thì f = -∞
Try(1); //tim x1
}
* Nhận xét:
- Nếu không kiểm tra điều kiện g(a1, …,ak) ≤ f thì thuật toán trở thành thuật toán duyệt toàn bộ
các phương án.
- Hàm g(x) cần xây dựng đơn giản để việc tính g được nhanh chóng 3.2.3 Giải một số bài toán bằng thuật toán nhánh cận: