python回溯方法的模板_Python基于回溯法子集树模板解决0-1背包问题实例
本文實例講述了Python基于回溯法子集樹模板解決0-1背包問題。分享給大家供大家參考,具體如下:
問題
給定N個物品和一個背包。物品i的重量是Wi,其價值位Vi ,背包的容量為C。問應該如何選擇裝入背包的物品,使得放入背包的物品的總價值為最大?
分析
顯然,放入背包的物品,是N個物品的所有子集的其中之一。N個物品中每一個物品,都有選擇、不選擇兩種狀態。因此,只需要對每一個物品的這兩種狀態進行遍歷。
解是一個長度固定的N元0,1數組。
套用回溯法子集樹模板,做起來不要太爽!!!
代碼
'''0-1背包問題'''
n = 3 # 物品數量
c = 30 # 包的載重量
w = [20, 15, 15] # 物品重量
v = [45, 25, 25] # 物品價值
maxw = 0 # 合條件的能裝載的最大重量
maxv = 0 # 合條件的能裝載的最大價值
bag = [0,0,0] # 一個解(n元0-1數組)長度固定為n
bags = [] # 一組解
bestbag = None # 最佳解
# 沖突檢測
def conflict(k):
global bag, w, c
# bag內的前k個物品已超重,則沖突
if sum([y[0] for y in filter(lambda x:x[1]==1, zip(w[:k+1], bag[:k+1]))]) > c:
return True
return False
# 套用子集樹模板
def backpack(k): # 到達第k個物品
global bag, maxv, maxw, bestbag
if k==n: # 超出最后一個物品,判斷結果是否最優
cv = get_a_pack_value(bag)
cw = get_a_pack_weight(bag)
if cv > maxv : # 價值大的優先
maxv = cv
bestbag = bag[:]
if cv == maxv and cw < maxw: # 價值相同,重量輕的優先
maxw = cw
bestbag = bag[:]
else:
for i in [1,0]: # 遍歷兩種狀態 [選取1, 不選取0]
bag[k] = i # 因為解的長度是固定的
if not conflict(k): # 剪枝
backpack(k+1)
# 根據一個解bag,計算重量
def get_a_pack_weight(bag):
global w
return sum([y[0] for y in filter(lambda x:x[1]==1, zip(w, bag))])
# 根據一個解bag,計算價值
def get_a_pack_value(bag):
global v
return sum([y[0] for y in filter(lambda x:x[1]==1, zip(v, bag))])
# 測試
backpack(0)
print(bestbag, get_a_pack_value(bestbag))
效果圖
更多關于Python相關內容感興趣的讀者可查看本站專題:《Python數據結構與算法教程》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》及《Python入門與進階經典教程》
希望本文所述對大家Python程序設計有所幫助。
時間: 2017-08-30
總結
以上是生活随笔為你收集整理的python回溯方法的模板_Python基于回溯法子集树模板解决0-1背包问题实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 买黄金理财怎么买?黄金投资的时机
- 下一篇: python以下导入包的格式错误的是_I