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的组合:

Python 初学笔记:递归解决0-1背包问题_第1张图片

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

你可能感兴趣的:(Python)