回溯法解决0_1背包问题python代码
0_1背包问题是经典的组合优化问题,我们使用回溯法构造子集树对其求解,并通过剪枝函数减小搜索的空间。
import copy
#子集树
def BacktrackBag(t):
global rest # 剩余背包容量
global restp # 当前未装入背包的总价值
global cw # 背包当前载重量
global cp # 背包当前装入价值
global bestp # 背包当前最优装入价值
global x # 解空间树表征数组
global w # 物品重量数组
global p # 物品价值数组
global bestx #最优表征数组
if t >= n:
if cp == bestp:
bestx = copy.deepcopy(x)
#if bestp >= cp:
# print(x,'当前最优解:%.0f'% bestp)
else:
for i in range(1,-1,-1):
x[t] = i
#如果该物品可以放入,并且之后的物品比当前价值优进行递归
if rest >= x[t]*w[t] and cp + restp - p[t] * (1-x[t]) >= bestp:
rest = rest - x[t]*w[t]
cp = cp + p[t]*x[t]
restp = restp - p[t]
if cp >= bestp:
bestp = cp
BacktrackBag(t+1)
rest = rest + x[t] * w[t]
cp = cp - p[t] * x[t]
restp = restp + p[t]
if __name__=='__main__':
# 3-2,2,3-1,1,10-4
glist =input().split('-')
# 物品个数
n=int( glist[0])
# 背包容量
c=int ( glist[len(glist)-1])
# 剩余背包容量
rest=c
items=glist[2].split(',')
# 物品价值数组
p=[int(item) for item in items]
items=glist[1].split(',')
# 物品重量数组
w=[int(item) for item in items]
# 背包当前载重量
cw=0
# 背包当前装入价值
cp=0
# 当前未装入背包的总价值
restp=0
for i in p:
restp=restp+i
# 背包当前最优装入价值
bestp=0
# 解空间树表征数组
x=[0 for i in range(n)]
print('物品个数:',str(n))
print('物品重量数组:',str(w))
print('物品价值数组:',str(p))
print('背包容量:',str(c))
BacktrackBag(0)
print(bestx,'当前最优解:%.0f'% bestp)
输入输出样例:
4-2,1,3,2-12,10,20,15-5
物品个数: 4
物品重量数组: [2, 1, 3, 2]
物品价值数组: [12, 10, 20, 15]
背包容量: 5
[1, 1, 0, 1] 当前最优解:37