回溯法解決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