Python 0-1背包2行如何查找元素

Python 0-1背包2行如何查找元素,python,algorithm,knapsack-problem,Python,Algorithm,Knapsack Problem,课后 我只使用两行实现了一个有效的0-1背包算法。 输出正确的最终值。 名称包含正在使用的每个元素的id def KnapSack(val, wt, n, W): names = n n = len(n) mat = [[0 for i in range(W + 1)] for i in range(2)] i = 0 while i < n: j = 0 if i % 2 == 0:

课后
我只使用两行实现了一个有效的0-1背包算法。
输出正确的最终值。
名称包含正在使用的每个元素的id

def KnapSack(val, wt, n, W): 
    names = n
    n = len(n)
    mat = [[0 for i in range(W + 1)] for i in range(2)] 

    i = 0
    while i < n: 
        j = 0 

        if i % 2 == 0: 
            while j < W:
                j += 1
                if wt[i] <= j:
                    mat[1][j] = max(val[i] + mat[0][j - wt[i]], mat[0][j]) 
                else:
                    mat[1][j] = mat[0][j] 
        else: 
            while j < W: 
                j += 1
                if wt[i] <= j: 
                    mat[0][j] = max(val[i] + mat[1][j - wt[i]], mat[1][j]) 
                else: 
                    mat[0][j] = mat[1][j] 
        i += 1
    if n % 2 == 0: 
        return mat[0][W] 
    else: 
        return mat[1][W] 
def背包(val、wt、n、W): 名称=n n=len(n) mat=[[0代表范围内的i(W+1)]代表范围内的i(2)] i=0 而i如果wt[i]就像普通背包一样,那么您必须在
DP
数组中跟踪您是如何达到这个特定状态的。因此,在您的
mat
表中,我们不跟踪结果和,而是跟踪构成它的元素-表中的每个条目现在都是一个元组,包含和和和名称列表

我还对您的代码进行了一次重要的重构——您是否看到代码中的
if
else
子句有多相似?我们可以通过基于
i%2
的逻辑将它们联合起来-在我的代码中,这是
cur
。这允许我们只写这些逻辑-这是0-1背包的一个相当常见的技巧。一般来说,您应该尽可能避免复制粘贴,因为这通常是错误的来源。如果没有,进一步说明,代码如下:

def KnapSack(val, wt, n, W): 
    names = n
    n = len(n)
    mat = [[(0, []) for i in range(W + 1)] for i in range(2)] 

    i = 0
    while i < n: 
        j = 0 
        cur = i % 2

        while j < W:
            j += 1
            if wt[i] <= j:
                if val[i] + mat[cur][j - wt[i]][0] > mat[cur][j][0]:
                    mat[1 - cur][j] = (val[i] + mat[cur][j - wt[i]][0], mat[cur][j - wt[i]][1][:] + [names[i]])
                else:
                    mat[1 - cur][j] = (mat[cur][j][0], mat[cur][j][1][:])
            else:
                mat[1 - cur][j] = (mat[cur][j][0], mat[cur][j][1][:]) 

        i += 1
    if n % 2 == 0: 
        return mat[0][W] 
    else: 
        return mat[1][W] 

print(KnapSack([7, 8, 4], [3, 8, 6], ['apple', 'box', 'peach'], 10))
def背包(val、wt、n、W): 名称=n n=len(n) mat=[(0,[])表示范围内的i(W+1)]表示范围内的i(2)] i=0 而i 打印
(11,['apple','peach'])
,因为11是最佳值,由第一和第三元素组成

请注意额外的
[:]
来复制列表-列表没有被深度复制,这会打乱我们的解决方案,因为我们会不断地反复修改相同的列表


祝你学习顺利

mat将包含背包的最终结果,在我的例子中是58。我试图找到最后的元素,这些元素加在一起,我想我部分理解。在新的max函数中,我将存储一个用于生成max值的当前元素数组,但是在运行算法后,存储的值不会开始重复吗?你能提供一个例子吗?你能提供max函数的伪代码吗?我很难理解你的意思。在找到更好的max时保存解决方案值,如果max得到改进,则覆盖以前的值。当达到最佳最大值且迭代结束时,如果存在多个解决方案,则当前解决方案值将是一个答案;如果存在唯一的全局最大值,则当前解决方案值将是一个答案。