Python 初学笔记:递归解决0-1背包问题

最近看了Magnus Lie Hetland的《Python基础教程(第2版)》158页利用生成器和递归解决八皇后问题的内容,于是想用这种方法解决0/1背包问题,所以仿照基础教程写了一段代码,基本上能够解决问题,但是明显还有不足之处,先记录下,以后慢慢修改。。。


def conflict(m, w, state, pos):
    total = 0
    for i in state:
        total += w[i]
    if total <= m and total + w[pos] > m:
        return True
    else:
        return False

def knapsacks(m, w, state=()):
    n = len(w)
    for i in range(n):
        if i not in state:
            if not conflict(m, w, state, i):
                for result in knapsacks(m, w, state + (i,)):
                    yield (i,) + result
            else:
                yield ()

def max_knapsack(m = 10, w = (2,2,6,5,4), p = (6,3,5,4,6)):
    knss = list(knapsacks(m, w))
    ps = []
    for kns in knss:
        total = 0
        for k in kns:
            total += p[k]
        ps.append(total)
    return max(ps)

def main():
    m = raw_input("Input weight constraint of knapsacks: ")
    n = raw_input("Input the number of goods: ")
    w = raw_input("Input each weight of the %s goods (e.g., 2,3,5,...): " % n)
    p = raw_input("Input each value of the %s goods (e.g., 2,3,5,...): " % n)
    m = float(m)
    n = int(n)
    ws = w.split(',')
    ps = p.split(',')
    w = []
    p = []
    for i in range(n):
        w.append(float(ws[i]))
        p.append(float(ps[i]))
    print "Max value: ", max_knapsack(m, w, p)

main()

从结果上明显可看出knapsacks和conflict方法还有一些不足之处。


knapsacks方法返回的可能所有满足总重量小于m的组合:


由于递归方法写得不好,导致出现多个重复的元组。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值