最近看了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的组合:
由于递归方法写得不好,导致出现多个重复的元组。