理解背包蛮力计划

时间:2017-10-25 00:47:12

标签: python parameters knapsack-problem

我被朋友给了一个我想了解的背包蛮力计划。这是我给出的代码:

def knapSack(W, wt, val, n):

    if n == 0 or W == 0:
        return 0


    if (wt[n - 1] > W):
        return knapSack(W, wt, val, n - 1)


    else:
        return max(val[n - 1] + knapSack(W - wt[n - 1], wt, val, n - 1),
               knapSack(W, wt, val, n - 1))




values = [10, 500, 786]
wt = [1, 2, 0.5]
weight = 2
n = len(values)
print(knapSack(weight   , wt, values, n))

我不明白这是如何运作的:

if (wt[n - 1] > W):
return knapSack(W, wt, val, n - 1)

我也不明白这是如何运作的:

else:
    return max(val[n - 1] + knapSack(W - wt[n - 1], wt, val, n - 1),
               knapSack(W, wt, val, n - 1))

TBH我对这两条线如何工作一无所知,它们看起来像随机调用背包。我也不明白n-1的作用。

我知道它非常模糊,请求抱歉:)

2 个答案:

答案 0 :(得分:1)

背包问题的基础是:给定一组物品,每个物品都有一个值和一个重量,在给定的重量限制下找到最有价值的物品组合。

这些是您问题中的变量(除此之外:您朋友的命名惯例非常糟糕)。

此问题有两个终端案例:

  1. 没有剩余物品

  2. 没有重量

  3. 该程序如何解决这些问题?

    if n == 0 or W == 0:
            return 0
    

    第二个代码块是另一个案例

    正在测试的物品超出重量限制

    if (wt[n - 1] > W):
            return knapSack(W, wt, val, n - 1)
    

    这只是意味着尝试对背包算法进行另一次迭代,并删除当前正在测试的项目。

    这里的else块是拼图的最后一块

    被测物品未超过重量限制

    else:
        return max(val[n - 1] + knapSack(W - wt[n - 1], wt, val, n - 1),
               knapSack(W, wt, val, n - 1))
    

    这究竟是什么意思?返回最多两个选项:

    1. 当前项目的值+再次使用较低的权重限制(W-wt [n-1]部分)执行背包算法的值和排除的项目(n-1部分) )。

    2. 背包算法,当前项目被排除,权重限制相同(想想当前项目很重,但不值得多,这个选项可能会更高)。

    3. 这是有效的,因为您实际上是在说这个项目的价值,添加它,调整重量,看看最好的剩余组合是什么,或者不包括这个项目,以及看看剩下的最好的组合是什么。这将测试子选项的每种可能组合。

      这整个事情是一个被称为Dynamic Programming的范例的例子。我建议阅读一些类似于此问题的简单例子。一旦你找到解决这些问题的方法,理解它们就会变得容易得多。

答案 1 :(得分:0)

以上并非严格意义上的动态编程。在DP中有一个表,并且代码没有潜力达到Python中的递归深度限制。

def unboundedKnapsack(W, n, val, wt):

    dp = [0 for i in range(W + 1)]

    ans = 0

    for i in range(W + 1):
        for j in range(n):
            if (wt[j] <= i):
                dp[i] = max(dp[i], dp[i - wt[j]] + val[j])

    return dp[W]

W = 60
val = [ 1, 20]
wt = [1, 30]


n = len(val)

print(unboundedKnapsack(W, n, val, wt))