Очень хороший вопрос!
Вы дважды правы
- Распространение количества предметов в рюкзаке не приводит к оптимальным решениям.
- Одно решение состоит в добавлении третьего измерения. Это довольно просто, но при этом необходимо учитывать некоторые факты. Обратите внимание, что это не единственная альтернатива
Далее я предполагаю, что вы знакомы с решением, основанным на динамическом программировании. В частности, я не буду обсуждать, как пройти таблицу назад, чтобы определить решение .
Давайте сначала сосредоточимся на типичном случае: количество предметов не ограничено . В этом случае вы просто строите таблицу где T i , j содержит оптимальное значение, когда общая вместимость рюкзака равна i, и рассматриваются только первые j элементов. Отсюда:TTя , джяJ
Tя , дж= max { TI , J - 1, Тя - шJ, J - 1+ VJ}
где и v jвесJvJ обозначают вес и стоимость элемента соответственно. Если С является общая мощность котомке и есть в общей сложности N элементов оптимальное решение дается T C , N . Известно, что этот алгоритм работает в псевдополиномиальном времени, и одна из его прелестей заключается в том, что он рассматривает только те комбинации, которые соответствуют максимальной емкости.JСNTС, N
Однако этого недостаточно при добавлении ограничения: максимальное количество элементов . Причина в том, что предыдущая формула повторения не учитывает различные комбинации элементов:п
- Во-первых, если то T i , j = ( T i - wTI , J - 1< ( Tя - шJ, J - 1+ VJ)так чтоJ-й предмет добавляется в рюкзак, несмотря на максимальное количество рассматриваемых предметов,pTя , дж= ( Tя - шJ, J - 1+ VJ)Jп--- чтобы вы могли нарушать свои ограничения. Что ж, у вас может возникнуть соблазн применить предыдущую формулу, отслеживая количество предметов, вставленных на каждом шаге, и не добавлять другие, если количество предметов в рюкзаке превышает но,п
- Во-вторых, если то T i , j = T i , j - 1, так что этот элемент не добавляется, но это может быть большой ошибкой в случае оптимального решения T i , j - 1TI , J - 1> ( Tя - шJ, J - 1+ VJ)Tя , дж= ТI , J - 1TI , J - 1уже состоит из максимального количества предметов для вставки в рюкзак. Причина в том, что мы не сравниваем должным образом: с одной стороны, чтобы сохранить оптимальное решение, состоящее из элементов, выбранных среди предыдущих ( j - 1 ) ; с другой стороны, чтобы вставить j-й элемент и, дополнительно, рассмотреть наилучшее подмножество с ( p - 1 ) элементами среди предыдущих ( j - 1 ) .п( J - 1 )J( р - 1 )( J - 1 )
Так что первое решение состоит из добавления третьего измерения. Для вашего случая, пусть будет оптимальным решением, когда вместимость рюкзака равна i , учитываются только первые j предметов, и в рюкзак не разрешается помещать более k предметов. Сейчас,Tя , J , KяJК
- Если вы вычисляете для количества элементов, строго меньшего или равного количеству элементов, которые можно вставить ( j ≤ k ), то продолжайте как обычно, но используя то же значение k : T i , j , k = max { T i , j - 1 , k , T i -Tя , J , Kj ≤ kКTя , J , K= max { Ti , j - 1 , k, Тя - шJ, j - 1 , к+ VJ}
- Теперь, если вам нужно вычислить для количества элементов, строго превышающего количество элементов, которые можно вставить ( j > k ), то: T i , j , k = max { T i , j - 1 , k , T i - w j , j - 1 , k - 1 + v j }Tя , J , KJ > KTя , J , K= max { Ti , j - 1 , k, Тя - шJ, j - 1 , k - 1+ VJ}
Первое выражение должно быть понятным. Второе работает, поскольку -й слой таблицы 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 )К
Надеюсь это поможет,