Проблема с ранцем - объяснение рекурсивного решения - PullRequest
0 голосов
/ 26 октября 2018

У меня проблемы с пониманием того, как и почему работает это наивное рекурсивное решение. Если бы мне дали эту проблему впервые, я бы подумал о том, чтобы провести исчерпывающий поиск (итеративно) со всеми возможными комбинациями, записать и вернуть максимальное значение в конце. Может кто-нибудь объяснить, пожалуйста, это решение?

code from CSDojo

Код от CSDojo

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

Решение в основном пытается для элемента n либо вставить его (только если он все еще подходит), либо опустить его, а затем поместить оставшиеся элементы как можно лучше (рекурсивные вызовы). Это дает два значения tmp1 и tmp2. Затем требуется максимум из них.

0 голосов
/ 26 октября 2018

Это решение работает, потому что логика звука.Давайте запишем эту логику в слова:

Максимальное значение для емкости C, используя любой из первых до n th элементов:

def KS(n, C):

Если мы не используем какие-либо элементыили у нас нет емкости, тогда у нас нулевое значение:

If n == 0 or C == 0:
  result = 0

В противном случае, если вес этого (n th) элемента больше, чем эта емкость (C), используйте лучший результатмы можем получить за эту емкость (C) без этого предмета.Это решение для Max value for capacity C, using any of the first to (n-1)th items (помните, что текущий расчет ищет KS(n, C), поэтому нам не разрешается использовать какие-либо элементы после n th в списке):

else if w[n] > C:
  result = KS(n - 1, C)

В противном случаедавайте решим, следует ли нам использовать этот элемент или нет:

else:

Если мы не используем n -й элемент, это то же самое, что и наша предыдущая возможность: решение для Max value for capacity C, using any of the first to (n-1)th items:

  tmp1 = KS(n - 1, C)

Если мы его используем, так как текущий расчет ищет решение для емкости C, давайте добавим текущее значение v[n] к нашему решению, используя любой из предыдущих n-1предметов, но с емкостью C - current_weight, так что вместе с текущим весом w[n] мы представим решение, которое по-прежнему оставляет емкость C:

  tmp2 = v[n] + KS(n - 1, C - w[n])

Выберите более высокое значение:

  result = max{ tmp1, tmp2 }

Верните правильный результат для наших текущих параметров:

return result 

Рекурсия может быть немного нелогичной.Вызов KS(n, C) сгенерирует целую кучу вызовов с «более ранними» параметрами n - 1, n - 2 и т. Д. И меньшей пропускной способностью, из-за чего кажется, что эти вызовы происходят после первоначального вызова,Но на самом деле KS(n, C) ожидает завершения всех тех, чтобы ответить на свой собственный расчет, чтобы мы могли точно сказать, что это происходит после «более ранних» вызовов параметров.И многие из них могут повторяться, когда значения параметров совпадают, поэтому может быть полезно кэшировать их для ускорения процедуры.

Также может быть полезно рассматривать n, C как «поиск»пространство »формулировки.Это означает, что мы действительно ограничены n * C различными комбинациями параметров.Вот почему некоторые рекурсии, такие как рюкзак, часто представлены в виде итерации по n и C (например, вложенные циклы for).

0 голосов
/ 26 октября 2018

Этот метод может выполнить исчерпывающий поиск.

Это реализация эвристики ветвлений и границ, где условие if обрезает текущую ветвь, потому что она не может расти дальше.

Без этого алгоритма обрезки создается полное двоичное дерево для всех возможных подмножеств (tmp1 и tmp2 - выбор - используем ли мы текущий элемент)

...