我被朋友给了一个我想了解的背包蛮力计划。这是我给出的代码:
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的作用。
我知道它非常模糊,请求抱歉:)
答案 0 :(得分:1)
背包问题的基础是:给定一组物品,每个物品都有一个值和一个重量,在给定的重量限制下找到最有价值的物品组合。
这些是您问题中的变量(除此之外:您朋友的命名惯例非常糟糕)。
此问题有两个终端案例:
没有剩余物品
没有重量
该程序如何解决这些问题?
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))
这究竟是什么意思?返回最多两个选项:
当前项目的值+再次使用较低的权重限制(W-wt [n-1]部分)执行背包算法的值和排除的项目(n-1部分) )。
背包算法,当前项目被排除,权重限制相同(想想当前项目很重,但不值得多,这个选项可能会更高)。
这是有效的,因为您实际上是在说这个项目的价值,添加它,调整重量,看看最好的剩余组合是什么,或者不包括这个项目,以及看看剩下的最好的组合是什么。这将测试子选项的每种可能组合。
这整个事情是一个被称为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))