利用動態規劃演算法,尋找每個狀態下揹包內物品的最優解,最終得出最終最優解。
執行說明:
7個.dat字尾檔案儲存了7組位址資料儲存於data資料夾中,將.py和.exe檔案放在data的父級資料夾中。直接執行01packet.exe,將顯示每組資料的原始數值,和揹包價值最優解以及放入揹包的物品序號。程式視窗將保持300秒。
資料結構:
整型product_count:物品數量
整型capacity:揹包容量
列表weight_array:物品重量
列表value_array:物品價值
演算法設計:
1、首先從配置檔案中獲取物品數量、揹包容量、物品重量和物品價值,分別存入上述對應的資料結構中。
2、定義乙個二維列表value,其行數為物品數量+1,其列數為揹包容量+1,初始化二維列表中所有值為0。
3、value[i][j]代表當前揹包剩餘容量j的條件下,前i個物品的最優解。
4、在每一種容量條件下遍歷每一件物品,將現有狀態value與前一狀態value對比,即當揹包可以裝下物品i,且裝下比不裝下的value值更大,則裝入。
5、遞迴完成二維列表value的每一值設定,二維列表內最大值即為最優解(價值最大)。
6、從最優解處回溯,當二維列表第i行大於第i-1行同一位置的值時,則代表放入第i個物品,並減去對應重量。
7、回溯至value[0][0],可得出放入的所有物品。
# -*- coding: utf-8 -*-
import time
import glob
# 定義01揹包問題的類
class
packet
:#初始化引數物品數量,揹包容量,重量,價值
def__init__
(self,product_count,capacity,weight_array,value_array)
: self.product_count = product_count
self.capacity = capacity
self.weight_array = weight_array
self.value_array = value_array
# data函式用於列印每組資料
defdata
(self)
('物品個數:'
, self.product_count)
('揹包容量:'
, self.capacity)
('商品重量:'
, self.weight_array)
('商品價值:'
, self.value_array)
# 動態規劃演算法
defdynamic_planning
(self)
:#value[i][j]:當前揹包容量 j,前 i 個物品最佳組合對應的價值,初始化置0,
value =[[
0for j in
range
(self.capacity +1)
]for i in
range
(self.product_count +1)
]# 利用迴圈使每乙個物品遍歷揹包容量
for i in
range(1
, self.product_count +1)
:for j in
range(1
, self.capacity +1)
: value[i]
[j]= value[i -1]
[j]# 將揹包置於放入上乙個物品的狀態(前一狀態)
# 當揹包剩餘容量大於等於當前物品,且前一狀態價值(由於上一條語句,此時前一狀態為value[i][j])小於現狀態價值時,置換
if j >=
int(self.weight_array[i -1]
)and value[i]
[j]< value[i -1]
[j -
int(self.weight_array[i -1]
)]+int
( self.value_array[i -1]
):value[i]
[j]= value[i -1]
[j -
int(self.weight_array[i -1]
)]+int
(self.value_array[i -1]
)return value
# 列印最優解
defshow
(self)
:# 從最優解處遍歷物品,當value大於上一行同樣位置的value時,表示放進該物品
value = self.dynamic_planning(
('最大價值為:'
, value[self.product_count]
[self.capacity]
) x =
[false
for i in
range
(self.product_count)
] j = self.capacity
for i in
range
(self.product_count,0,
-1):
if value[i]
[j]> value[i -1]
[j]:
#此行大於上一行同位置的值
x[i -1]
=true
# 放入該物品
j -=
int(self.weight_array[i -1]
)# 減少對應揹包容量
('揹包中所裝物品為:'
)for i in
range
(self.product_count)
:if x[i]
('第'
+str
(i +1)
+'個 '
, end=
' ')
defmain()
:file
= glob.glob(
'./data/*.dat'
)# 獲取指定目錄下所用.dat字尾檔案
for i,filename in
enumerate
(file):
# 迴圈獲取序號與檔名
# filename = "input_assign01_0"+str(i+1)+".dat"
('\n\n第%d組資料'
%(i+1)
)# 開啟檔案,逐行讀取資料
with
open
(filename,
'r')
as f:
product_count = f.readline(
) capacity = f.readline(
) weight_array = f.readline(
) value_array = f.readline(
)# 將重量與價值轉化為列表形式
weight_array = weight_array.strip(
).split(
" ")
value_array = value_array.strip(
).split(
" ")
product_count =
int(product_count)
capacity =
int(capacity)
packet(product_count, capacity, weight_array, value_array)
.data(
)# 呼叫類方法data
packet(product_count, capacity, weight_array, value_array)
.show(
)# 呼叫類方法show
('\nfinish!'
) time.sleep(
300)
if __name__ ==
'__main__'
: main(
)
北京工業大學CSDN高校俱樂部運營策劃
申請理由 我們是一群對it行業有著無限熱情的新一代大學生,本著對我們專業的熱愛與嚮往走到一起,相互取長補短,共同進步。希望在這個行業內,通過我們自己的合作和努力,可以開啟屬於我們自己的一片天空。俱樂部定位 我們組員在一起就是好朋友好夥伴,我們的俱樂部以學習交流為主。每個人都會收穫新的技術,我們會定期...
2023年哈爾濱工業大學計算機研究生機試真題
題目描述 給定a和n,計算a aa aaa a.a n個a 的和。輸入 測試資料有多組,輸入a,n 1 a 9,1 n 100 輸出 對於每組輸入,請輸出結果。樣例輸入 1 10 樣例輸出 1234567900 include includeusing namespace std int resul...
合肥工業大學機械人技術作業二
合肥工業大學機械人技術作業二 題目描述 用物件導向的思維設計相關類,從而實現直線與直線 直線與圓 直線與矩形的交點。要求各給出每個案例的至少乙個示例的程式。演算法思想 1.直線與直線可採用ax by c 0來判斷,具體 為 x c otherline.b b otherline.c b otherl...