В задаче о жадном грабителе и рюкзаке (см. раздел «Эвристические алгоритмы»
function powdered_knapsack(items, max_weight)
····bag_weight ← 0
····bag_items ← List.new
····items ← sort_by_value_weight_ratio(items)
····for each i in items
········weight ← min(max_weight — bag_weight,
·····················i.weight)
········bag_weight ← bag_weight + weight
········value ← weight * i.value_weight_ratio
········bagged_value ← bagged_value + value
········bag_items.append(item, weight)
····return bag_items, bag_value
Добавление ограничения неделимости предметов только уменьшит максимально возможную прибыль, потому что нам придется менять последнюю уложенную в рюкзак вещь на что-то подешевле. Это означает, что powdered_knapsack дает верхнюю границу оптимальной прибыли с неделимыми предметами[43].
Ветви и границы в задаче о рюкзаке
Мы уже убедились, что поиск оптимальной прибыли в задаче о рюкзаке требует дорогих вычислений
Предмет | Стоимость | Вес | Соотношение стоимости и веса | Макс. вместимость |
---|---|---|---|---|
A | 20 | 5 | 4,00 | |
B | 19 | 4 | 4,75 | |
C | 16 | 2 | 8,00 | 10 |
D | 14 | 5 | 2,80 | |
E | 13 | 3 | 4,33 | |
F | 9 | 2 | 4,50 |
Рисунок справа иллюстрирует ситуацию перед началом заполнения рюкзака. В первом поле находятся неупакованные предметы, которые нам предстоит рассмотреть. Второе поле представляет свободное место в рюкзаке и предметы, которые уже уложены. Выполнение функции greedy_knapsack дает прибыль 39, а powdered_knapsack — 52,66. Это означает, что оптимальная прибыль находится где-то посередине. Как мы знаем из раздела «Разделяй и властвуй», эта задача с
Мы вычисляем верхнюю и нижнюю границы для этих двух подзадач. Каждая имеет нижнюю границу, равную 48: теперь мы знаем, что оптимальное решение находится между 48 и 52. Давайте рассмотрим подзадачу справа, поскольку у нее более интересные границы:
Крайняя левая подзадача имеет самую многообещающую верхнюю границу. Давайте продолжим наш анализ и выполним разбиение этой подзадачи:
Теперь мы можем сделать важные выводы. Выделенная цветом подзадача имеет нижнюю границу 49, которая равна ее верхней границе. Это означает, что оптимальная прибыль здесь должна равняться
Рациональное использование верхних и нижних границ позволило нам найти оптимальную прибыль, выполнив совсем немного вычислений. Мы динамически адаптировали наше пространство поиска по мере анализа возможностей.
Вот общие принципы работы метода ветвей и границ:
1) разделить задачу на подзадачи;
2) найти верхние и нижние границы каждой подзадачи;
3) сравнить границы подзадач всех ветвей;
4) выбрать самую многообещающую задачу и вернуться к шагу 1.
Если вы помните, стратегия поиска с возвратом (см. соответствующий раздел) тоже позволяет найти решение без обследования каждого возможного варианта. В случае поиска с возвратом мы исключаем пути, изучив каждый из них так далеко, как это возможно, и останавливаемся, когда нас устраивает решение. В случае же с методом ветвей и границ мы заранее определяем бесперспективные пути и не тратим впустую энергию на их обследование.
Подведем итоги
Решение задач, в сущности, представляет собой перемещение по пространству возможностей с целью найти правильный вариант. Мы узнали несколько способов, как это делается. Самый простой — полный перебор, то есть последовательная проверка каждого элемента в пространстве поиска.