python解決0 1揹包問題(超直觀)

2021-08-15 10:56:25 字數 2422 閱讀 9035

但是太詳盡了,而且太自頂向下,符號一多更容易搞蒙頭。那麼我就從自底向上,來得出動態規劃的狀態轉移方程吧。

來看乙個0-1揹包的例子:

weight=[2,2,6,5,4]

value=[3,6,5,4,6]

weight_most=10

有5個物體,考慮裝入揹包,揹包的總承重是10。第乙個物體重2,價值是3,如此類推。那麼怎樣才能在不超過揹包承重的範圍下,使得揹包裝的物體的總價值最高呢?哈哈,先考慮一些簡單的情況如果只允許裝前1件物體,不,這樣還不夠簡單。

自底向上分析:

1、最簡單是只允許裝前0件物體,即什麼都不裝,那這樣的話,管你揹包承重0也好,10也好,100也好。那麼總價值最高都是0。

2、好了,難一點點,只允許裝前1件物體,也就是只允許裝第1件了。那麼不要馬上跳到承重10,先從承重0開始,如果揹包只允許承重0的話,那麼總價值最高也是0。|承重1呢,第一件物體重2,裝不下,怎麼辦呢,那就不裝唄還能怎麼辦,瞄一眼前0件(也就是不裝)承重1的情況,總價值是0,所以總價值還是0咯。|好了,承重是2呢?2-2=0裝得下,裝的話比前0件(不裝)承重2的總價值要高!那你裝不裝?肯定要裝,那麼總價值最高就是3。|那麼承重是3呢?3-2=1,還有1的重量可以裝,臥槽,可是裝不了,因為,只允許裝前一件,如果換個說法的話,就是在承重1的情況下允許裝前0件(哈哈,就是不給裝嘛)。那麼不用看之後承重是5也好,10也好,總價值最高就是3。

3、只允許裝前1件還是很簡單的,那麼好戲來了!!!允許裝前兩件呢?承重0,總價值最高0,不用看。|承重1呢,裝不下,看前1件(不裝)承重1是0,那麼前2件承重1是0。|承重2呢,關鍵了!允許裝前2件,兩件都裝得下,那比較一下吧,是允許裝前1件承重2總價值比較高呢?還是?對,還是什麼?還是我新允許的第2件價值比較高呢,怎麼比較規範表達呢?因為這件是裝得下,2-2=0,那麼裝完之後呢?是不是回歸到允許前1件承重0的情況了?很好,那麼加上這種情況的總價值最高為0,0+6>3,所以前2件承重2總價值最高就是6了。前2件承重3也差不多。|承重4呢?是前1件承重4總價值為3比較高呢?還是裝了第二件之後,回歸到前1件承重2,加起來,3+6=9比較高呢?那麼就是9!|前5件,承重10咧?

4、回到我們的總問題,emmmmm,你應該心裡有b數了。不就3種情況嘛,承重0或者允許裝前0件,全是總價值最高0;如果新允許的第i件裝的那件裝不下,那就看允許的前i-1件對應的承重的總價值最高咯;如果裝得下,那麼就要比較允許裝前i-1件對應的承重的總價值最高這承重減去新裝的那件,回歸到那種情況的總價值最高相加。沒了,就三種情況,狀態轉移方程就這樣出來了。

實現**如下:

import numpy as np

weight=[2,2,6,5,4]

value=[3,6,5,4,6]

weight_most=10

def bag_0_1(weight,value,weight_most):#return max value

num = len(weight)

weight.insert(0,0)#前0件要用

value.insert(0,0)#前0件要用

bag=np.zeros((num+1,weight_most+1),dtype=np.int32)#下標從零開始

for i in range(1,num+1):

for j in range(1,weight_most+1):

if weight[i]<=j:

bag[i][j]=max(bag[i-1][j-weight[i]]+value[i],bag[i-1][j])

else:

bag[i][j]=bag[i-1][j]

# print(bag)

return bag[-1,-1]

result=bag_0_1(weight,value,weight_most)

print(result)

輸出:
15
如果你想看bag這個矩陣也可以:
[[ 0  0  0  0  0  0  0  0  0  0  0]

[ 0 0 3 3 3 3 3 3 3 3 3]

[ 0 0 6 6 9 9 9 9 9 9 9]

[ 0 0 6 6 9 9 9 9 11 11 14]

[ 0 0 6 6 9 9 9 10 11 13 14]

[ 0 0 6 6 9 9 12 12 15 15 15]]

以上。

動態規劃揹包問題 01揹包(超詳細)

問題背景 設有容量為v的揹包,有n種物品,每件物品的體積是c i 對應的價值是v i 每種物品只有乙個,要使揹包中所裝物品的價值總和最大,問該如何選擇。用乙個二維陣列f i j 來表示i件物品,在用j的容量時的最大的價值。因為對於每一件物品,你選擇就只能是裝或者不裝這件物品。例如 物品 a b c ...

0 1揹包問題python 0 1揹包問題1

鼓搗好久 終於了然了一些 0 1揹包問題描述 有乙個竊賊在偷竊一家商店時發現有n件物品,第i件物品價值為vi元,重量為wi,假設vi和wi都為整數。他希望帶走的東西越值錢越好,但他的揹包中之多只能裝下w磅的東西,w為一整數。他應該帶走哪幾樣東西?注 0 1揹包問題中 每件物品或被帶走,或被留下,需要...

0 1揹包問題 python

測試資料 n 6 物品的數量,c 10 書包能承受的重量,w 2,2,3,1,5,2 每個物品的重量,v 2,3,1,5,4,3 每個物品的價值 def bag1 n,c,w,v value 0for j in range c 1 for i in range n 1 i 物品 1 i for i ...