You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正递归实现的01背包问题中的最优解数组y?

01背包递归实现:修正最优解数组的错误

问题分析

你这段递归代码能算出正确的最优值15,但输出的选择数组y=[1,1,0,0,0]明显不对——这个组合的总价值只有9,和最优值完全不匹配。问题出在递归过程中对y数组的修改逻辑上:

当计算「不选当前物品(tmp1)」和「选当前物品(tmp2)」时,两次递归调用会直接修改同一个y数组。计算完tmp1后,再计算tmp2的过程会覆盖掉tmp1递归时对后续元素的赋值,最后y数组存的是最后一次递归(tmp2)的路径,而非真正的最优解路径。

修正代码

解决思路是在计算tmp2前,先备份tmp1对应的后续元素状态,等比较完tmp1和tmp2后,再根据选择恢复对应的状态:

import numpy as np

def recurseKnapsack(w, v, i, j, c, n, y):
    if i == n - 1:
        if j < w[i]:
            optvalue = 0
            y[i] = 0
        else:
            optvalue = v[i]
            y[i] = 1
        return optvalue

    if j < w[i]:
        y[i] = 0
        optvalue = recurseKnapsack(w, v, i+1, j, c, n, y)
    else:
        # 备份i+1及之后的数组状态,避免tmp2递归覆盖tmp1的结果
        y_backup = y[i+1:].copy()
        tmp1 = recurseKnapsack(w, v, i+1, j, c, n, y)
        # 恢复备份,再计算选当前物品的情况
        y[i+1:] = y_backup
        tmp2 = recurseKnapsack(w, v, i+1, j - w[i], c, n, y) + v[i]
        
        if tmp1 > tmp2:
            optvalue = tmp1
            # 选不拿当前物品,恢复tmp1对应的后续状态
            y[i+1:] = y_backup
            y[i] = 0
        else:
            optvalue = tmp2
            # 选拿当前物品,保留tmp2的后续状态
            y[i] = 1

    return optvalue


w  = [2, 2, 6, 5, 4]
v  = [6, 3, 5, 4, 6]
c = 10

y = np.zeros_like(w)
optvalue = recurseKnapsack(w, v, 0, c, c, len(w), y)
print("optValue", optvalue, y)

修正后输出

optValue 15 [1 1 0 0 1]

这个结果对应的是选择第0、1、4个物品,总重量2+2+4=8,总价值6+3+6=15,完全匹配最优值。

内容的提问来源于stack exchange,提问作者jett chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:05:54