回溯法求解0-1背包问题

# -*- coding=utf-8 -*-

class BackSack:  # 定义背包类
    def __init__(self, capacity, weight, value):  # 类的初始化
        # 背包最大容量
        self.capacity = capacity
        # 质量
        self.weight = weight
        # 价值
        self.value = value
        # 数量
        self.length = len(weight)
        # 选取矩阵
        self.goods = [0] * self.length
        # 背包当前重量
        self.currentWeight = 0
        # 背包可容纳货物的最大价值
        self.bestValue = 0
        # 当前已装货物的价值
        self.currentValue = 0
        # 当前容量
        self.currentCapacity = 0
        # 最优解
        self.bestGoods = None

    # 遍历解空间寻找最优值
    def back_track(self, i):
        # i 当前搜索的深度
        # 搜索到底
        if i >= self.length:
            if self.currentValue > self.bestValue:  # 更新最优值
                self.bestValue = self.currentValue
                self.currentCapacity = self.currentWeight  # 当前最优解下的背包重量
                self.bestGoods = self.goods[:]
            return
        # 进入左子树,即选取goods[i]放入背包
        if self.currentWeight + self.weight[i] <= self.capacity:
            # 选择i
            self.goods[i] = 1
            # 更新质量
            self.currentWeight += self.weight[i]
            # 更新价值
            self.currentValue += self.value[i]
            # 下一层
            self.back_track(i + 1)
            # 进入右子树,即舍弃goods[i],不放入背包
            self.currentValue -= self.value[i]
            self.currentWeight -= self.weight[i]
            self.goods[i] = 0
        self.back_track(i + 1)

def main():
    # 重量
    weight = list()
    # 价值
    value = list()
    # 容量
    capacity = int(input('请输入容量:'))
    # 物品数目
    num = int(input('请输入物品数目:'))
    for i in range(num):
        w = int(input('请输入第%d个物品质量:' % (i + 1)))
        v = int(input('请输入第%d个物品价值:' % (i + 1)))
        weight.append(w)
        value.append(v)
    # 调用回溯法
    b = BackSack(capacity=capacity, weight=weight, value=value)
    b.back_track(0)
    # 输出
    print('物品质量向量为', weight)
    print('物品价值向量为', value)
    print("最优解:", b.bestGoods)
    print("最优值:", b.bestValue)

if __name__ == '__main__':
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值