Python基于回溯法子集樹模板解決0-1背包問題實例
本文實例講述了Python基于回溯法子集樹模板解決0-1背包問題。分享給大家供大家參考,具體如下:
問題
給定N個物品和一個背包。物品i的重量是Wi,其價值位Vi ,背包的容量為C。問應該如何選擇裝入背包的物品,使得放入背包的物品的總價值為最大?
分析
顯然,放入背包的物品,是N個物品的所有子集的其中之一。N個物品中每一個物品,都有選擇、不選擇兩種狀態(tài)。因此,只需要對每一個物品的這兩種狀態(tài)進行遍歷。
解是一個長度固定的N元0,1數(shù)組。
套用回溯法子集樹模板,做起來不要太爽?。。?/p>
代碼
'''0-1背包問題'''
n = 3 # 物品數(shù)量
c = 30 # 包的載重量
w = [20, 15, 15] # 物品重量
v = [45, 25, 25] # 物品價值
maxw = 0 # 合條件的能裝載的最大重量
maxv = 0 # 合條件的能裝載的最大價值
bag = [0,0,0] # 一個解(n元0-1數(shù)組)長度固定為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: # 超出最后一個物品,判斷結果是否最優(yōu)
cv = get_a_pack_value(bag)
cw = get_a_pack_weight(bag)
if cv > maxv : # 價值大的優(yōu)先
maxv = cv
bestbag = bag[:]
if cv == maxv and cw < maxw: # 價值相同,重量輕的優(yōu)先
maxw = cw
bestbag = bag[:]
else:
for i in [1,0]: # 遍歷兩種狀態(tài) [選取1, 不選取0]
bag[k] = i # 因為解的長度是固定的
if not conflict(k): # 剪枝
backpack(k+1)
# 根據(jù)一個解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))])
# 根據(jù)一個解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數(shù)據(jù)結構與算法教程》、《Python函數(shù)使用技巧總結》、《Python字符串操作技巧匯總》及《Python入門與進階經典教程》
希望本文所述對大家Python程序設計有所幫助。
相關文章
Python使用異步線程池如何實現(xiàn)異步TCP服務器交互
這篇文章主要介紹了Python使用異步線程池如何實現(xiàn)異步TCP服務器交互問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
使用python腳本自動創(chuàng)建pip.ini配置文件代碼實例
這篇文章主要介紹了使用python腳本自動創(chuàng)建pip.ini配置文件代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-09-09
YOLOv5車牌識別實戰(zhàn)教程(一)引言與準備工作
這篇文章主要介紹了YOLOv5車牌識別實戰(zhàn)教程(一)引言與準備工作,在這個教程中,我們將一步步教你如何使用YOLOv5進行車牌識別,幫助你快速掌握YOLOv5車牌識別技能,需要的朋友可以參考下2023-04-04

