01揹包問題從簡單到複雜

2021-09-01 00:04:28 字數 3472 閱讀 5471

有 n 件物品和乙個容量為 v 的揹包。放入第 i 件物品耗費的費用是 c i 1 ,得到

的價值是 w i 。求解將哪些物品裝入揹包可使價值總和最大。

f [i, v] = max

這裡的出口容易搞錯,出口可以從遞推方程成立條件來考慮

def

pack_0_1_rec2

(n,v,c,w)

:if n ==0:

return

0if v < c[n-1]

:return pack_0_1_rec(n-

1,v,c,w)

return

max(pack_0_1_rec(n-

1,v,c,w)

,pack_0_1_rec(n-

1,v-c[n-1]

,c,w)

+ w[n-1]

)

# 後來仔細考慮出後之後,做了如下修正:

defpack_0_1_top_down

(n,v,c,w)

:list=[

[-1]

*(v+1)

for i in

range

(n+1)]

# mins = min(c)

# for i in range(n+1):

# for j in range(v+1):

# if i == 0 or j< mins:

# list[i][j] =0

list[0

]=[0

]*(v+1

)def

pack_0_1_top_down_

(n,v)

:# if list[n][v] == -1 and n >=1 and v >=mins:

iflist

[n][v]==-

1and n >=1:

a = pack_0_1_top_down_(n-

1,v)

if v < c[n-1]

:return a

else

:list

[n][v]

=max

(a,pack_0_1_top_down_(n-

1,v-c[n-1]

)+w[n-1]

)return

list

[n][v]

return pack_0_1_top_down_(n,v)

defpack_0_1_bottom_up

(n,v,c,w)

:list=[

[-1]

*(v+1)

for i in

range

(n+1)]

list[0

]=[0

]*(v+1

)for i in

range(1

,n+1):

for j in

range(0

,v+1):

a =list

[i-1

][j]

if j < c[i-1]

:list

[i][j]

= a

else

:list

[i][j]

=max

(a,list

[i-1

][j-c[i-1]

]+w[i-1]

)# print list

return

list

[n][v]

凡是基於去與不去的問題,均可使用如下方式

def

pack_0_1_first

(n,v,c,w)

:def

zeroonepack

(f,ci,wi)

:for v in

range

(v,ci-1,

-1):

f[v]

=max

(f[v]

,f[v-ci]

+ wi)

return f

f =[0

]*(v+1

)for i in

range(1

,n+1):

zeroonepack(f,c[i-1]

,w[i-1]

)return f[v]

可行性問題,想清楚初始條件

如果是,要求恰好裝滿揹包,那麼在初始化時除了 f [0] 為 0 ,其

它 f [1…v ] 均設為 −∞ ,這樣就可以保證最終得到的 f [v ] 是一種恰好裝滿揹包的最優解。

如果並沒有要求必須把揹包裝滿,而是只希望**盡量大,初始化時應該將 f [0…v ] 全部設為 0 。

這是為什麼呢?可以這樣理解:初始化的 f 陣列事實上就是在沒有任何物品可以放入揹包時的合法狀態。

如果要求揹包恰好裝滿,那麼此時只有容量為 0 的揹包可以在什麼也不裝且價值為 0 的情況下被「恰好裝滿」,

其它容量的揹包均沒有合法的解,屬於未定義的狀態,應該被賦值為-∞了。

如果揹包並非必須被裝滿,那麼任何容量的揹包都有乙個合法解「什麼都不裝」,這個解的價值為 0 ,

所以初始時狀態的值也就全部為 0 了。

def

pack_0_1_yes_or_no

(n,v,c)

:def

zeroonepack

(f,ci)

:for v in

range

(v,ci-1,

-1):

f[v]

= f[v-ci]

or f[v]

return f

f =[-

1]*(v+1)

f[0]

=true

for i in

range(1

,n+1):

zeroonepack(f,c[i-1]

)return f[v]

#%%

n =6

v =23

c =[1,

3,4,

5,17,

11]w =[2,

9,7,

5,11,

4]#%%print pack_0_1_rec(n,v,c,w)

print pack_0_1_first(n,v,c,w)

print pack_0_1_top_down(n,v,c,w)

print pack_0_1_bottom_up(n,v,c,w)

print pack_0_1_rec2(n,v,c,w)

print pack_0_1_yes_or_no(n,v,c)

2525

2525

25true

簡單0 1揹包問題

有乙個揹包能裝的重量maxw 正整數,0 maxw 20000 同時有n件物品 0 n 100 每件物品有乙個重量wi 正整數 和乙個價值pi 正整數 要求從這n件物品中任取若干件裝入揹包內,使揹包的物品價值最大。第1行 揹包最大載重maxv,物品總數n 第2行到第n 1行 每個物品的重量和價值 乙...

裝箱問題 簡單01揹包問題)

題目描述 description 有乙個箱子容量為v 正整數,0 v 20000 同時有n個物品 0 n 30 每個物品有乙個體積 正整數 要求n個物品中,任取若干個裝入箱內,使箱子的剩餘空間為最小。輸入描述 input description 乙個整數v,表示箱子容量 乙個整數n,表示有n個物品 ...

揹包問題 01揹包問題

n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...