Câu hỏi rất hay!
Bạn đúng hai lần:
- Tuyên truyền số lượng vật phẩm trong ba lô không dẫn đến giải pháp tối ưu.
- Một giải pháp bao gồm thêm một chiều thứ ba. Điều này khá đơn giản nhưng cần phải tính đến một số sự thật khi làm như vậy. Lưu ý tuy nhiên đó không phải là sự thay thế duy nhất
Sau đây, tôi giả sử rằng bạn đã quen thuộc với giải pháp dựa trên lập trình động. Cụ thể, tôi sẽ không thảo luận về cách di chuyển ngược bảng để xác định giải pháp .
Trước tiên chúng ta hãy tập trung vào trường hợp điển hình: số lượng vật phẩm không bị hạn chế . Trong trường hợp này, bạn chỉ cần xây dựng một bảng trong đó T i , j chứa giá trị tối ưu khi công suất tổng thể của chiếc ba lô bằng i và chỉ các mục j đầu tiên được xem xét. Từ đây:TTi,jij
Ti,j=max{Ti,j−1,Ti−wj,j−1+vj}
trong đó và ứng với trọng lượng và giá trị của mục thứ . Nếu là công suất tổng thể của chiếc ba lô của bạn và có tổng số mặt hàng thì giải pháp tối ưu được đưa ra bởi . Thuật toán này được biết là chạy trong thời gian giả đa thức và một trong những nét đẹp của nó là nó chỉ xem xét những kết hợp phù hợp với công suất tối đa.v j j C N T C , NwjvjjCNTC,N
Tuy nhiên, điều này là không đủ khi thêm ràng buộc của bạn: số lượng mục tối đa . Lý do là công thức lặp lại trước đó không tính đến các kết hợp khác nhau của các mục:p
- Đầu tiên, nếu thì sao cho những -thứ mục được thêm vào ba lô mặc dù số lượng tối đa các mặt hàng xem xét, --- để bạn có thể vi phạm hạn chế của bạn. Chà, bạn có thể bị cám dỗ ở đây để áp dụng công thức trước đó theo dõi số lượng vật phẩm được chèn ở mỗi bước và không thêm các vật phẩm khác nếu số lượng vật phẩm hiện tại trong ba lô vượt quá nhưng,Ti,j−1<(Ti−wj,j−1+vj)Ti,j=(Ti−wj,j−1+vj)jpp
- Thứ hai, nếu thì để mục này không được thêm nhưng đó có thể là một sai lầm lớn trong trường hợp giải pháp tối ưu đã bao gồm số lượng vật phẩm tối đa để chèn vào ba lô. Lý do là chúng tôi không so sánh đúng: một mặt, để bảo tồn giải pháp tối ưu bao gồm các mục được chọn trong số các mục trước ; mặt khác, để chèn mục thứ và, ngoài ra, hãy xem xét tập hợp con tốt nhất với các mục trong số các mục trước .Ti,j−1>(Ti−wj,j−1+vj)Ti,j=Ti,j−1Ti,j−1p(j−1)j(p−1)(j−1)
Vì vậy, một giải pháp đầu tiên bao gồm thêm một chiều thứ ba. Đối với trường hợp của bạn, hãy để là giải pháp tối ưu khi công suất của ba lô là , chỉ các mục đầu tiên được xem xét và không được phép đặt nhiều hơn mục trong ba lô. Hiện nay,Ti,j,kijk
- Nếu bạn đang tính toán cho một số mục hoàn toàn nhỏ hơn hoặc bằng số lượng mục có thể được chèn ( ) thì hãy tiếp tục như bình thường nhưng sử dụng cùng giá trị của :Ti,j,kj≤kkTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k+vj}
- Bây giờ, nếu bạn phải tính cho một số mục lớn hơn số lượng mục có thể được chèn ( ) thì:Ti,j,kj>kTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k−1+vj}
Biểu thức đầu tiên phải rõ ràng. Lớp thứ hai hoạt động kể từ lớp thứ của bảng theo dõi sự kết hợp tốt nhất của các mục trong số thứ nhất theo yêu cầu ở trên.(k−1)T(k−1)(j−1)
Việc triển khai hiệu quả thuật toán này không cần tính cho tất cả . Lưu ý rằng các mối quan hệ lặp lại trước đó liên quan đến lớp với và do đó, có thể xen kẽ giữa hai lớp liên tiếp (ví dụ: nếu bạn quan tâm đến giải pháp tối ưu với bạn chỉ cần sử dụng hai lớp liên tiếp: 0 và 1, 1 và 2, 2 và 3, 3 và 4 và bạn đã hoàn thành). Nói cách khác, thuật toán này chiếm gấp đôi bộ nhớ theo cách tiếp cận truyền thống dựa trên lập trình động và do đó, nó vẫn có thể chạy trong thời gian giả đa thức. k k ( k - 1 ) k = 4Ti,j,kkk(k−1)k=4
Tuy nhiên, hãy lưu ý rằng đây không phải là giải pháp duy nhất! Và có một cái khác bạn có thể tìm thấy thanh lịch hơn. Trong các công thức trước, chúng tôi đã truy xuất giải pháp tối ưu bao gồm không quá mục trong số các mục đầu tiên là . Tuy nhiên, cần phải rõ ràng rằng điều này chính xác bằng chỉ bằng cách sử dụng bảng gốc !! tức là, có thể lấy ra giải pháp tối ưu với không quá mục bằng cách xem xét các giải pháp tối ưu với 1 mục, 2 mục, 3 mục, ...( j - 1 ) T i , j - 1 , k - 1 tối đa p = 0 , j - 1 { T i , p } k ( j - 1 ) k(k−1)(j−1)Ti,j−1,k−1maxp=0,j−1{Ti,p}k(j−1)các mục ... Để làm cho công thức này hoạt động, bạn cũng nên theo dõi số lượng các mục được xem xét trong mỗi giải pháp một phần để bạn sẽ cần hai số nguyên cho mỗi ô. Việc chiếm dụng bộ nhớ này dẫn đến chính xác các yêu cầu bộ nhớ tương tự của thuật toán được hiển thị ở trên (sử dụng chiều thứ ba ở dạng lớp )k .
Hi vọng điêu nay co ich,