北京工業大學研究生演算法作業(二) 01揹包問題

2021-10-01 11:14:08 字數 4243 閱讀 9518

利用動態規劃演算法,尋找每個狀態下揹包內物品的最優解,最終得出最終最優解。

執行說明:

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)

:print

('物品個數:'

, self.product_count)

print

('揹包容量:'

, self.capacity)

print

('商品重量:'

, self.weight_array)

print

('商品價值:'

, 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(

)print

('最大價值為:'

, 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]

)# 減少對應揹包容量

print

('揹包中所裝物品為:'

)for i in

range

(self.product_count)

:if x[i]

:print

('第'

+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"

print

('\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

print

('\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...