Bài tốn cái túi nguyên.

Một phần của tài liệu Thuật toán và một số thuật toán sơ cấp (Trang 37 - 40)

2. QUY HOẠCH ĐỘNG 1 Mở đầu

2.2. Bài tốn cái túi nguyên.

lượng (là các số nguyên) khác nhau cần chọn để bỏ vào một cái túi cĩ thể đựng được trọng lượng tối đa là g. Cần chọn các đồ vật sao cho tổng giá trị các đồ vật trong túi là lớn nhất.

Ví dụ: Túi cĩ trọng lượng g=17, các đồ vật cĩ trọng lượng và giá trị tương ứng là: A(3,4), B(4,5), C(7,10), D(8,11), E(9,13). Ta cĩ thể cĩ một số phương án chọn như bảng ở trang sau.

Ta cĩ bảng sau liệt kê một số phương án chọn các đồ vật: Các đồ vật Tổng trọng lượng Tổng giá trị A, A, A, A, A 15 20 D, E 17 24 A, B, E 16 22 A, C, C 17 24 B, B, D 16 21 Một số phương án chọn đồ vật.

Theo kỹ thuật quy hoạch động ta sẽ tính các phương án tốt nhất cho tất cả các trọng lượng túi từ 1 cho tới g.

Gọi c(i,j) là giá trị lớn nhất cĩ thể đ được với túi ạt cĩ trọng lượng i mà chỉ dùng các đồ vật từ 1 tới j. Trọng lượng lớn nhất cĩ thể đ được theo yêu cầu bài tốn sẽ là cạt (g,n).

Ta gọi m là mảng các khối lượng của các đồ vật, val là mảng các giá trị của các đồ vật. Khi ta cĩ: c(k,1)= (k/đĩ m[1])*val[1], tức là nếu chỉ chọn các đồ vật loại 1 thì giá trị

của túi sẽ bằng số lượng tối đa đồ vật loại 1 cĩ thể chọn nhân với giá trị của đồ vật loại 1. Để tính c(i,j) thơng qua các giá trị đã tính được trước đĩ, ta nhận xét rằng khi xét thêm đồ vật thứ j ta cĩ 2 khả năng lựa chọn đồ vật:

- hoặc vẫn sử dụng j 1 loại đồ vật cũ mà khơng dùng tới đồ vật loại j - - hoặc cĩ sử dụng ít nhất một đồ vật loại j.

Như vậy c(i,j) cĩ thể xác định như sau:

c(i,j) = max(c(i,j-1) , c(i-m[j],j) +val[j]).

Chẳng hạn trong ví dụ trên, đầu tiên ta tính giá trị tối ưu cho tất cả các trọng lượng túi khi chỉ chọn một loại đồ vật A, sau đĩtính giá trịtối ưu cho tất cả các trọng lượng túi khi chỉ chọn hai loại đồ vật A và B, v.v.

Ta dùng mảng 1 chiều, thay vì tính c(i,j) ta sẽ tính c[j] ở bước thứ i. Cĩ thể mơ tả thuật tốn như sau:

int Caitui1(int n,int g); For (j=1;j<=n;j++) { For (i=1;i<=g;i++) {

If (i-m[j]>=0) { If (c[i]< c[i-m[j]]+val[j]) { c[i]= c[i-m[j]]+val[j] ; } }

}

Trong ví dụ đã nêu trước, thuật tốn sẽ tạo ra bảng sau:

i\j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 0 0 0 4 4 4 8 8 8 12 12 12 16 16 16 20 20 20 2 0 0 0 4 5 5 8 9 10 12 13 14 15 17 18 20 20 20 3 0 0 0 4 5 5 8 10 10 12 14 15 15 18 20 20 22 24 4 0 0 0 4 5 5 8 10 11 12 14 15 16 18 20 21 22 24 5 0 0 0 4 5 5 8 10 11 13 14 15 17 18 20 21 23 24 Và ta cĩ giá trị tối ưu là 24 cho túi cĩ trọng lượng 17.

Dựa vào bảng ta cĩ thể liệt kê các đồ vật được chọn cho một phương án tối ưu. Trong cột chứa giá trị tối ưu tìm được ta tìm dịng chứa giá trị này xuất hiện lần đầu tiên (trong ví , dụ là dịng ứng với đồ vật loại 3). Khi đĩ ta biết rằng đồ vật loại tương ứng được chọn trong phương án tối ưu.

Tiếp đĩ dựa vào bảng ta tìm được giá trị tối ưu (trong ví dụ là 14) cho túi cĩ trọng lượng bằng trọng lượng túi ban đầu trừ trọng lượng đồ vật đã chọn. Cứ tiếp tục như vậy cho tới khi

trọng lượng túi nhỏ hơn trọng lượng đồ vật nhẹ nhất.

Để liệt kê ra các đồ vật được chọn ứng với phương án tối ưu, ta dùng một mảng Chon để ghi nhận loại đồ vật được chọn mỗi khi cập nhật lại giá trị túi và bổ sung vào thủ tục Caitui1. Như vậy Chon[j] là loại đồ vật được chọn cuối cùng ứng với phương án tối ưu cho túi cĩ trọng lượng j.

Ta bổ sung thêm vào thuật tốn đã cĩ như sau: int Caitui2;

For (j=1;j<=n;j++) { Chon[j]= } 0; For (j=1;j<=n;j++) {

For (i=1;i<=g;i++) { If (i-m[j]>=0) {

If (c[i]< c[i-m[j]]+val[j]) { c[i]= c[i-m[j]]+val[j]; Chon[j]=i;} }

} }

Để liệt kê ta cĩ thuật tốn sau: void Lietke;

j= n;

While (Chon[j]<>0) {

Liệt kê đồ vật loại Chon[j]; j= j-m[Chon[j]];

}

Một phần của tài liệu Thuật toán và một số thuật toán sơ cấp (Trang 37 - 40)

Tải bản đầy đủ (PDF)

(71 trang)