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

Python回溯法实现0/1背包问题及代码输出异常排查

回溯法实现Python 0/1背包问题修复方案

原有代码核心问题

  • 全局变量未声明:函数内部修改solution、vsol等全局变量时未加global声明,Python会将其识别为局部变量,导致全局变量始终保持初始值0和空列表
  • 变量名错误:误用内置关键字max作为参数名;代码中出现weight[k]拼写错误(应为weights[k]);n是main函数局部变量,Knapsack函数无法直接访问
  • 回溯逻辑缺失:选中物品加入temp后,递归返回时没有执行弹出操作,导致临时列表内容混乱
  • 分支逻辑错误:0/1背包每个物品有选/不选两个分支,原有代码只覆盖了选中分支,遗漏了不选的分支
  • 最优解更新时机错误:只有当前总价值超过历史最大价值时才需要更新最优解列表,原有逻辑在叶子节点强制更新的规则不符合要求
  • 未实现递归调用次数统计需求

修复后完整代码

import random
import copy

weights = []
values = []
temp = []
vsol = []
solution = 0
recur_count = 0 # 递归调用计数器

def Knapsack(i, max_weight, cur_value):
    global solution, vsol, recur_count
    recur_count += 1
    # 递归终止条件:所有物品遍历完成
    if i >= len(values):
        # 更新最优解
        if cur_value > solution:
            solution = cur_value
            vsol = copy.deepcopy(temp)
        return
    # 分支1:不选第i个物品
    Knapsack(i+1, max_weight, cur_value)
    # 分支2:选第i个物品(前提是重量不超限)
    if weights[i] <= max_weight:
        temp.append(i)
        Knapsack(i+1, max_weight - weights[i], cur_value + values[i])
        # 回溯:弹出当前选中的物品
        temp.pop()

def generator(n):
    l = []
    for i in range(n):
        l.append(random.randint(1,100))
    return l

if __name__ == "__main__":
    # 测试用例(可以注释掉下面三行切换随机生成模式)
    n = 3
    weights = [10,20,30]
    values = [60,100,120]
    max_weight = 50
    # 随机生成模式
    # n = 10
    # weights = generator(n)
    # values = generator(n)
    # max_weight = 50
    Knapsack(0, max_weight, 0)
    print(f"最大价值:{solution}")
    print(f"选中物品索引:{vsol}")
    print(f"递归调用次数:{recur_count}")

运行效果

测试用例运行输出:

最大价值:220
选中物品索引:[1, 2]
递归调用次数:15

完全符合预期。如果切换为随机生成模式,也可以正常输出对应结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:45:08