Tổng quat
Câu trả lời của Jeff Shattock là chính xác rằng điều này tương đương (hoặc đẳng cấu, như các nhà toán học viết) cho một vấn đề tối ưu hóa tổ hợp, nhưng nó tương đương với vấn đề đóng gói bin 1 chiều , không phải là vấn đề về ba lô .
May mắn cho bạn, tôi có một số mã để chia sẻ sẽ giải quyết vấn đề này cho bạn hoặc bất kỳ ai khác, với quyền truy cập vào máy tính Windows có cài đặt ít nhất phiên bản 3.5 của .NET Framework.
Một giải pháp thô
Đầu tiên, tải xuống và cài đặt LINQPad .
Thứ hai, tải xuống truy vấn LINQPad tôi vừa viết - đây là linq (ha) vào tệp thô. Lưu nó dưới dạng tệp .linq và mở nó trong LINQPad.
Thay đổi các tham số:
Đây là một phần trong mã truy vấn LINQPad bạn nên thay đổi:
int binSizeMb = 4476; // This is the (floor of the) total size of a DVD+R reported by CDBurnerXP.
string rootFileFolderPath = @"F:\2006 - Polyester Pimpstrap Intergalactic Extravaganza multicam";
Thay đổi binSizeMb
kích thước của 'bin' của bạn, ví dụ: CD, DVD, ví dụ. int binSizeMb = 650;
cho một đĩa CD.
Lưu ý - binSizeMb
giá trị được hiểu là những gì đôi khi được gọi là mebibyte . Trái ngược với thời thơ ấu của tôi, khi tất cả các bội số byte là 'nhị phân', đôi khi 'MB' bây giờ đề cập đến 'megabyte thập phân' hoặc chính xác là 1.000.000 byte, trái ngược với 1.048.576 byte của mebibyte (MiB), được sử dụng trong mã của tôi . Nếu bạn muốn thay đổi điều này, hãy thay đổi dòng const int bytesPerMb = 1048576;
trong mã thành const int bytesPerMb = 1000000;
.
Thay đổi rootFileFolderPath
đường dẫn đầy đủ của thư mục chứa các tệp bạn muốn 'đóng gói vào thùng', ví dụ: string rootFileFolderPath = @"C:\MySecretBinFilesFolder";
.
Chạy truy vấn bằng cách nhấn F5hoặc nhấp vào nút Thực thi ở phía trên bên trái của tab truy vấn.
Các kết quả
Mã truy vấn sẽ liệt kê tất cả các tệp trong rootFileFolderPath
thư mục, theo cách đệ quy, có nghĩa là nó cũng sẽ bao gồm các tệp trong tất cả các thư mục con.
Sau đó, nó sẽ tạo 'thùng' cho các tệp sao cho tổng kích thước của tất cả các tệp trong mỗi thùng nhỏ hơn hoặc bằng kích thước thùng được chỉ định.
Trong khung kết quả LINQPad, bạn sẽ thấy hai danh sách.
Danh sách đầu tiên là tất cả các tệp mà nó tìm thấy, được liệt kê theo thứ tự giảm dần theo kích thước.
Danh sách thứ hai là các thùng được tạo bằng cách 'đóng gói các tệp', với một danh sách các tệp và kích thước của chúng, cũng như kích thước còn lại của thùng.
Đây là một ảnh chụp màn hình hiển thị danh sách thứ hai và hai thùng đầu tiên được tạo:
Phân tích chữ thảo
Theo Wikipedia, thuật toán tôi đã sử dụng - chiến lược Giảm tốc độ phù hợp đầu tiên (FFD) - không nên quá tệ; Wikipedia nêu:
Vào năm 2007, người ta đã chứng minh rằng ràng buộc 11/9 OPT + 6/9 cho FFD là chặt chẽ.
'OPT' đề cập đến chiến lược tối ưu (như một thứ có khả năng không thể truy cập được, không phải bất kỳ chiến lược thực tế cụ thể nào).
Dựa trên những ký ức có phần mờ nhạt của tôi về các thuật ngữ toán học có liên quan, điều này có nghĩa là chiến lược FFD, tệ nhất là, đóng gói các mặt hàng vào ~ 1,22 lần số thùng mà một chiến lược tối ưu sẽ có. Vì vậy, chiến lược này có thể đóng gói các mục thành 5 thùng thay vì 4. Tôi nghi ngờ rằng hiệu suất của nó có thể rất gần với tối ưu ngoại trừ các kích thước mục 'bệnh lý' cụ thể.
Bài báo Wikipedia tương tự cũng nói rằng có một "thuật toán chính xác" . Tôi có thể quyết định thực hiện điều đó quá. Tôi sẽ phải đọc bài viết mô tả thuật toán trước.