Дуже приємне запитання!
Ви вдвічі праві:
- Поширення кількості предметів у рюкзаку не призводить до оптимальних рішень.
- Одне рішення полягає у додаванні третього виміру. Це досить просто, але потрібно враховувати деякі факти, роблячи це. Однак зауважте, що це не єдина альтернатива
Далі я припускаю, що ви знайомі з рішенням, заснованим на динамічному програмуванні. Зокрема, я не буду обговорювати, як пересувати таблицю назад, щоб визначити рішення .
Спершу зупинимось на типовому випадку: кількість предметів необмежена . У цьому випадку ви просто побудуєте таблицю де містить оптимальне значення, коли загальна ємність рюкзака дорівнює і враховуються лише перші елементи. Звідси:TTi,jij
Ti,j=max{Ti,j−1,Ti−wj,j−1+vj}
де і означають вагу і значення -го елемента відповідно. Якщо - це загальна ємність вашого рюкзака, а в ньому всього елементів, то оптимальне рішення дає . Цей алгоритм, як відомо, працює в псевдополіномічний час, і одна з його красунь полягає в тому, що він розглядає лише ті комбінації, які відповідають максимальній потужності.wjvjjCNTC,N
Однак цього недостатньо при додаванні обмежень: максимальна кількість елементів . Причина полягає в тому, що попередня формула повторення не враховує різні комбінації елементів:p
- По-перше, якщо тоді так що в -й елемент додається в рюкзаку, не дивлячись на максимальну кількість елементів , що розглядаються --- так що ви могли б порушувати ваше обмеження. Що ж, вас може спокусити застосувати попередню формулу, відслідковуючи кількість елементів, вставлених на кожному кроці, і не додавати інших, якщо кількість предметів, які в даний час знаходяться в рюкзаку, перевищує але,Ti,j−1<(Ti−wj,j−1+vj)Ti,j=(Ti−wj,j−1+vj)jpp
- По-друге, якщо тоді так що цей елемент не додається, але це може бути великою помилкою, якщо оптимальне рішення вже складається з максимальної кількості предметів, які потрібно вставити в рюкзак. Причина в тому, що ми не порівнюємо належним чином: з одного боку, зберегти оптимальне рішення, що складається з предметів, вибраних серед попередніх ; з іншого боку, для вставки -го елемента та додатково розглянути кращий підмножина з елементів серед попередніх .Ti,j−1>(Ti−wj,j−1+vj)Ti,j=Ti,j−1Ti,j−1p(j−1)j(p−1)(j−1)
Так що перше рішення складається з додавання третього виміру. У вашому випадку, нехай є оптимальним рішенням, коли ємність рюкзака , вважаються лише перші елементи, і заборонено поміщати більше, ніж предметів у рюкзак. Тепер,Ti,j,kijk
- Якщо ви обчислюєте для ряду елементів, суворо менших або рівних кількості елементів, які можна вставити ( ), продовжуйте, як зазвичай, але використовуючи те саме значення :Ti,j,kj≤kkTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k+vj}
- Тепер, якщо вам доведеться обчислити для кількості елементів, строго більших за кількість елементів, які можна вставити ( ), тоді:Ti,j,kj>kTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k−1+vj}
Перший вираз повинен бути чітким. Другий працює, оскільки -й шар таблиці відстежує найкраще поєднання елементів серед перших як вимагається вище.(k−1)T(k−1)(j−1)
Для ефективної реалізації цього алгоритму не потрібно обчислювати для всіх . Зауважте, що попередні співвідношення рецидивів стосуються шару з і, таким чином, можливо чергувати два послідовних шари (наприклад, якщо ви зацікавлені в оптимальному рішенні з ви просто використовуєте два послідовних шари: 0 і 1, 1 і 2, 2 і 3, 3 і 4, і ви закінчили). Іншими словами, цей алгоритм займає вдвічі більше пам’яті, необхідного традиційному підходу, заснованому на динамічному програмуванні, і, таким чином, він все ще може працювати в псевдополіномічний час.Ti,j,kkk(k−1)k=4
Однак майте на увазі, що це не єдине рішення! І є ще одна, яку ви можете виявити більш елегантною. У попередніх формулах ми знайшли оптимальне рішення, яке складалося з не більше пунктів серед перших як . Однак має бути зрозуміло, що це точно дорівнює лише за допомогою оригінальної таблиці !! Тобто, оптимальне рішення, що містить не більше елементів, можна також знайти, розглядаючи оптимальні рішення з 1 пунктом, 2 предметами, 3 предметами, ...(k−1)(j−1)Ti,j−1,k−1maxp=0,j−1{Ti,p}k(j−1)items ... Для того, щоб ця формулювання працювала, ви також повинні відслідковувати кількість елементів, що розглядаються у кожному частковому рішенні, так що вам знадобиться два цілих числа на комірку. Це заняття пам’яттю призводить до точно таких же вимог до пам'яті, як алгоритм, показаний вище (використовуючи третій вимір у вигляді шарів )k .
Сподіваюся, це допомагає,