Как бы вы подошли к проблеме ранца в ситуации динамического программирования, если теперь вам нужно ограничить количество предметов в ранце константой ? Это та же самая проблема (максимальный вес , каждый предмет имеет значение и вес ), но вы можете добавить только предмет (ы) в рюкзак и, очевидно, нужно оптимизировать значение рюкзака.W P
Нужно ли нам третье измерение или мы могли бы найти другой подход без него? Я попытался просто добавить номер элемента в рюкзаке в клетке и принимая максимальное значение в конце с числом п <= , но это не лучшее решение.
Ответы:
Очень хороший вопрос!
Вы дважды правы
Далее я предполагаю, что вы знакомы с решением, основанным на динамическом программировании. В частности, я не буду обсуждать, как пройти таблицу назад, чтобы определить решение .
Давайте сначала сосредоточимся на типичном случае: количество предметов не ограничено . В этом случае вы просто строите таблицу где T i , j содержит оптимальное значение, когда общая вместимость рюкзака равна i, и рассматриваются только первые j элементов. Отсюда:T Tя , дж я J
где и v jвесJ vJ обозначают вес и стоимость элемента соответственно. Если С является общая мощность котомке и есть в общей сложности N элементов оптимальное решение дается T C , N . Известно, что этот алгоритм работает в псевдополиномиальном времени, и одна из его прелестей заключается в том, что он рассматривает только те комбинации, которые соответствуют максимальной емкости.J С N TС, N
Однако этого недостаточно при добавлении ограничения: максимальное количество элементов . Причина в том, что предыдущая формула повторения не учитывает различные комбинации элементов:п
Так что первое решение состоит из добавления третьего измерения. Для вашего случая, пусть будет оптимальным решением, когда вместимость рюкзака равна i , учитываются только первые j предметов, и в рюкзак не разрешается помещать более k предметов. Сейчас,Tя , J , K я J К
Первое выражение должно быть понятным. Второе работает, поскольку -й слой таблицы T отслеживает наилучшую комбинацию ( k - 1 ) элементов среди первого ( j - 1 ), как требуется выше.( к - 1 ) T ( к - 1 ) ( J - 1 )
Эффективная реализация этого алгоритма не должна вычислять для всех k . Обратите внимание, что предыдущие рекуррентные отношения относятся к слою kTя , J , K К К с и, таким образом, можно чередовать два последовательных слоя (например, если вас интересует оптимальное решение с k = 4, вы просто используете два последовательных слоя: 0 и 1, 1 и 2, 2 и 3, 3 и 4 и все готово). Другими словами, этот алгоритм занимает в два раза больше памяти, чем требует традиционный подход, основанный на динамическом программировании, и, таким образом, он все еще может выполняться за псевдополиномиальное время.( к - 1 ) к = 4
Имейте в виду, однако, что это не единственное решение! И есть еще один, который вы можете найти более элегантным. В предыдущих формулах мы нашли оптимальное решение, которое состояло не более чем из элементов среди первых ( j - 1 ) как T i , j - 1 , k - 1 . Однако должно быть ясно, что это точно равно max p = 0 , j - 1 { T i , p }( к - 1 ) ( J - 1 ) Ti , j - 1 , k - 1 Максимумp = 0 , j - 1{ Tя , р} просто с помощью исходной таблицы! оптимальное решение с не более К элементов, также может быть получено путем рассмотрения оптимальных решений с 1 элементом, 2 элементами, 3 элементами, ... элементами ... Чтобы эта формулировка работала, вам следует Также следите за количеством элементов, рассматриваемых в каждом частичном решении, так что вам потребуется два целых числа на ячейку. Это заполнение памяти приводит к точно таким же требованиям к памяти алгоритма, показанного выше (с использованием третьего измерения в форме слоев k ) .( J - 1 ) К
Надеюсь это поможет,
источник