回溯法解决0_1背包问题python代码

回溯法解决0_1背包问题python代码

0_1背包问题是经典的组合优化问题,我们使用回溯法构造子集树对其求解,并通过剪枝函数减小搜索的空间。

import copy
#子集树
def BacktrackBag(t):
    global rest  # 剩余背包容量
    global restp  # 当前未装入背包的总价值
    global cw  # 背包当前载重量
    global cp  # 背包当前装入价值
    global bestp  # 背包当前最优装入价值
    global x  # 解空间树表征数组
    global w  # 物品重量数组
    global p  # 物品价值数组
    global bestx  #最优表征数组
    if t >= n:
        if cp == bestp:
            bestx = copy.deepcopy(x)
        #if bestp >= cp:
        # print(x,'当前最优解:%.0f'% bestp)
    else:
        for i in range(1,-1,-1):
            x[t] = i
            #如果该物品可以放入,并且之后的物品比当前价值优进行递归
            if rest >= x[t]*w[t] and cp + restp - p[t] * (1-x[t]) >= bestp:
                rest = rest - x[t]*w[t]
                cp = cp + p[t]*x[t]
                restp = restp - p[t]
                if cp >= bestp:
                    bestp = cp
                BacktrackBag(t+1)
                rest = rest + x[t] * w[t]
                cp = cp - p[t] * x[t]
                restp = restp + p[t]


if __name__=='__main__':
    # 3-2,2,3-1,1,10-4
    glist =input().split('-')
    # 物品个数
    n=int( glist[0])
    # 背包容量
    c=int ( glist[len(glist)-1])
    # 剩余背包容量
    rest=c
    items=glist[2].split(',')
    # 物品价值数组
    p=[int(item) for item in items]
    items=glist[1].split(',')
    # 物品重量数组
    w=[int(item) for item in items]
    # 背包当前载重量
    cw=0
    # 背包当前装入价值
    cp=0
    # 当前未装入背包的总价值
    restp=0
    for i in p:
        restp=restp+i
    # 背包当前最优装入价值
    bestp=0
    # 解空间树表征数组
    x=[0 for i in range(n)]
    print('物品个数:',str(n))
    print('物品重量数组:',str(w))
    print('物品价值数组:',str(p))
    print('背包容量:',str(c))

    BacktrackBag(0)
    print(bestx,'当前最优解:%.0f'% bestp)

输入输出样例:
4-2,1,3,2-12,10,20,15-5
物品个数: 4
物品重量数组: [2, 1, 3, 2]
物品价值数组: [12, 10, 20, 15]
背包容量: 5
[1, 1, 0, 1] 当前最优解:37

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

migrant-worker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值