Я полагаю, что цены целые и довольно небольшие, и вы думаете о каких-то школьных решениях DP.
ДП в целом
В алгоритмах динамического программирования для каждого состояния мы храним только одно лучшее частичное решение. Обычно мы не храним частичное решение физически: только его стоимость и некоторую простую информацию о возврате, чтобы восстановить ее позже. Мы не храним другие решения для состояния из-за свойства оптимальной подструктуры: любое частичное решение с худшей стоимостью имеет продолжения, которые хуже, чем такие же продолжения лучшего частичного решения.
Чтобы найти k лучших решений проблемы, вы можете просто сохранить k лучших частичных решений для каждого состояния DP. Если для какого-то состояния вообще меньше k решений, то сохраняем их все. Почему мы можем отбросить частичное решение, которое хуже, чем k других частичных решений? Потому что любое его продолжение будет хуже, чем такое же продолжение этих k лучших частичных решений.
Переходы в DP прямого стиля выполняются как обычно. Когда вы рассматриваете некоторое состояние, вы должны перебрать все его k лучших частичных решений и попытаться продолжить каждое из них всеми возможными способами (например, взять новый элемент или нет). Для каждого продолжения посмотрите на его состояние. Вставьте продолжение в отсортированный список лучших частичных решений. Если в результате получается k+1 частичных решений, худшее из них отбрасывается.
Наверняка вы не хотите хранить частичные решения в DP. Вместо этого сохраняйте только общую стоимость и информацию о возврате для каждого частичного решения. Информации о возврате должно быть достаточно, чтобы однозначно определить предыдущее частичное решение в DP. Таким образом, вы можете найти лучшие k решения. Кажется, что решение DP с k лучшими решениями требует в O(k) раз больше памяти и O(k^2) раз больше времени (или O(k log k)) для рюкзака по сравнению с поиском только одного лучшего решения.
Особая проблема
Мне кажется, что решать свою задачу следует двухуровневым алгоритмом:
- Запустите DP для задачи с ограниченным рюкзаком в каждой категории предметов. В результате вы получите k лучших комбинаций предметов категории с каждой общей стоимостью (и с ограниченным количеством предметов).
- Найдите оптимальную комбинацию решений, полученных на шаге 1. Необходимо взять по одному решению из каждой из рассматриваемых категорий.
Для одной категории решение DP для выбора s предметов из списка N предметов с размером рюкзака W, по-видимому, занимает O(s N W k^2) время. Объединение решений из категорий c на шаге 2 занимает O(c W^2 k^2), но его можно сократить до O(c W k log(W k)), если для слияния используется сбалансированное дерево.
person
stgatilov
schedule
27.08.2015