Огляд
Відповідь Джеффа Шаттока правильна, що це еквівалентно (або ізоморфно, як пишуть математики) проблемі комбінаторної оптимізації, але це еквівалентно 1-мірній проблемі упаковки у бін , а не проблемі рюкзака .
Пощастило для вас, я маю поділитися кодом, який вирішить цю проблему для вас чи когось іншого, з доступом до комп’ютера Windows із встановленою принаймні версією 3.5 .NET Framework.
Грубе рішення
Спочатку завантажте та встановіть LINQPad .
По-друге, завантажте запит LINQPad, про який я щойно писав - ось linkq (ha) до необробленого файлу. Збережіть його як .linq- файл і відкрийте його в LINQPad.
Змінення параметрів:
Ось частина коду запиту LINQPad, яку слід змінити:
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";
Змініть binSizeMb
розмір свого "кошика", наприклад CD, DVD, напр. int binSizeMb = 650;
для компакт-диска.
Примітка - binSizeMb
значення інтерпретується як те, що іноді називають мебібайт . На відміну від мого дитинства, коли всі кратні байти були "двійковими", іноді "MB" тепер посилається на "десятковий мегабайт" або рівно 1 000 000 байт, на відміну від 1048 576 байт мебібайт (MiB), який використовується в моєму коді . Якщо ви хочете змінити це, змініть рядок const int bytesPerMb = 1048576;
у коді на const int bytesPerMb = 1000000;
.
Перейдіть rootFileFolderPath
на повний шлях до папки, що містить файли, які ви хочете "спакувати в біни", напр. string rootFileFolderPath = @"C:\MySecretBinFilesFolder";
.
Запустіть запит, натиснувши F5або натисніть кнопку " Виконати" у верхньому лівому куті вкладки запитів.
Результати
Код запиту буде перераховувати всі файли в rootFileFolderPath
папці, рекурсивно, тобто він включає також файли у всіх папках.
Тоді він створить 'бункери' для файлів таким чином, що загальний розмір усіх файлів у кожному біні буде меншим або рівним вказаному розміру біна.
На панелі результатів LINQPad ви побачите два списки.
Перший список - це всі знайдені файли, перелічені у порядку зменшення за розміром.
Другий список - це бункери, створені за допомогою "упаковки файлів", зі списком файлів та їх розмірами, а також розміром залишків.
Ось скріншот, на якому показаний другий список та два створені перші бункери:
Короткий аналіз
Згідно з Вікіпедією, алгоритм, який я використовував, - стратегія First Fit зменшення (FFD) - не повинен бути надто поганим; У Вікіпедії зазначено:
У 2007 році було доведено, що зв'язані 11/9 OPT + 6/9 для FFD є жорсткими.
"OPT" означає оптимальну стратегію (як щось потенційно недосяжне, а не якусь конкретну стратегію).
Виходячи з моїх дещо нечітких спогадів про математичні терміни, це повинно означати, що стратегія FFD повинна, в гіршому випадку, упакувати предмети в ~ 1,22 рази більше кількості бункерів, що оптимальна стратегія. Отже, ця стратегія може упакувати предмети в 5 бункерів замість 4. Я підозрюю, що її ефективність може бути дуже близькою до оптимальної, за винятком конкретних "патологічних" розмірів предметів.
У тій же статті Вікіпедії також зазначено, що існує "точний алгоритм" . Я також можу вирішити це здійснити. Мені доведеться спочатку прочитати папір, яка описує алгоритм.