Python算法教程:背包问题

背包问题可用这一套术语来定义:有一组想要带在身边的物品,每个物品都有各自的质量和价值。但问题是背包有一个最大容量,如何才能使其中所带物品的总价值达到最高呢?

选取一些元素组成一个带权值的有限子集,使其权值最大化。

无限制背包问题

当作一个模式来看待:以某种形式来定义问题的子问题,递归这些子问题之间的关系,然后确保每个子问题都只被计算一次。

围绕这背包容量中最后一个单元是否有用来进行。

def unbound_knapsack(weights, values, capacity):
    res = [0]
    for cu in range(1, capacity+1):
        current = res[cu-1]
        for wi, wu in enumerate(weights):
            if wu > cu:
                continue
            current = max(current, values[wi]+res[cu-wu])
        res.append(current)
    return res[-1]


weights = [20, 10, 8]
values = [19, 31, 19]
capacity = 20
print(unbound_knapsack(weights, values, capacity))  # 62
0-1背包问题

每个对象最多只能用一次。

是否要纳入最后一个对象

def knapsack(weights, values, capacity):
    n = len(weights)
    res = [[0]*(capacity+1) for _ in range(n+1)]
    flag = [[False]*(capacity+1) for _ in range(n+1)]
    for nu in range(1, n+1):
        for cu in range(1, capacity+1):
            res[nu][cu] = pre = res[nu-1][cu]
            if weights[nu-1] > cu:
                continue
            current = values[nu-1] + res[nu-1][cu-weights[nu-1]]
            res[nu][cu] = max(pre, current)
            flag[nu][cu] = current > pre
    return res, flag


weights = [20, 10, 8]
values = [19, 31, 19]
capacity = 20

res, flag = knapsack(weights, values, capacity)
print(res[-1][-1])  # 50

wi, cur, items = len(weights), capacity, set()
while wi > 0 and cur > 0:
    if flag[wi][cur]:
        items.add(wi-1)
        cur -= weights[wi-1]
    wi -= 1
thing = {weights[i]: values[i] for i in items}
print(thing)    # {10: 31, 8: 19}

(最近更新:2019年09月06日)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值