動態規劃演算法 01揹包問題

2022-04-06 00:49:33 字數 3013 閱讀 4967

動態規劃演算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每乙個解都對應於乙個值,我們希望找到具有最優值的解。動態規劃演算法與分治法類似,其基本思想也是將待求解問題分解成若干個子問題,先求解子問題,然後從這些子問題的解得到原問題的解。與分治法不同的是,適合於用動態規劃求解的問題,經分解得到子問題往往不是互相獨立的(即下乙個子階段的求解是建立在上乙個子階段的解的基礎上,進行進一步的求解)。若用分治法來解這類問題,則分解得到的子問題數目太多,有些子問題被重複計算了很多次。如果我們能夠儲存已解決的子問題的答案,而在需要時再找出已求得的答案,這樣就可以避免大量的重複計算,節省時間。我們可以用乙個表來記錄所有已解的子問題的答案。不管該子問題以後是否被用到,只要它被計算過,就將其結果填入表中。這就是動態規劃法的基本思路。具體的動態規劃演算法多種多樣,但它們具有相同的填**式

適用動態規劃的問題必須滿足最優化原理、無後效性和重疊性。

1、最優化原理(最優子結構性質)

最優化原理可這樣闡述:乙個最優化策略具有這樣的性質,不論過去狀態和決策如何,對前面的決策所形成的狀態而言,餘下的諸決策必須構成最優策略。簡而言之,乙個最優化策略的子策略總是最優的。乙個問題滿足最優化原理又稱其具有最優子結構性質。

2、無後效性將各階段按照一定的次序排列好之後,對於某個給定的階段狀態,它以前各階段的狀態無法直接影響它未來的決策,而只能通過當前的這個狀態。換句話說,每個狀態都是過去歷史的乙個完整總結。這就是無後向性,又稱為無後效性。

3、子問題的重疊性下面是乙個關於0-1揹包問題的動態規劃思想ppt截圖:

問題描述:

給定n種物品和一揹包。物品i的重量是wi,其價值為vi,揹包的容量為c。問應如何選擇裝入揹包的物品,使得裝入揹包中物品的總價值最大?

對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1.我們設物品i的裝入狀態為xi,xi∈

(0,1),此問題稱為0-1揹包問題。

資料:物品個數n=5,物品重量w[n]=,物品價值v[n]=,

(第0位,置為0,不參與計算,只是便於與後面的下標進行統一,無特別用處,也可不這麼處理。)總重量c=10。揹包的最大容量為10,那麼在設定陣列m大小時,可以設行列值為6和11,那麼,對於m(i,j)就表示可選物品為i…n,揹包容量為j(總重量)時揹包中所放物品的最大價值。

當揹包為空時,首先分析將物品n放入揹包,即在總重量分別為0到10時,如何放置物品n使總價值最大。

對於m[5][j],當j=w[5]時,物品5可以放入揹包,此時揹包的價值為v[5]。得到結果如下表:

在物品5的基礎上分析物品4,

當j當j>=w[4]時,物品4要麼放入要麼不放入。當物品4放入揹包後,對於物品4+1到n,能達到的最大價值為m[4+1][j-w[4]]+v[4],故此時能達到的最大價值為m[4+1][j-w[4]]+v[4]

當物品4不放入揹包時,能達到的最大價值為m[4+1][j]。最後比較放入與不放入情況下,兩者的最大值取其大者,分析結果如下:

由前面分析過程得m[i][j]的遞迴過程如下:

最終得到如下結果:

最優解的構造可根據c列的資料來構造最優解,構造時從第乙個物品開始。從i=1,j=c即m[1][c]開始。  

1、對於m[i][j],如果m[i][j]==m[i+1][j],則物品i沒有裝入揹包,否則物品i裝入揹包;

2、為了確定後繼即物品i+1,應該尋找新的j值作為參照。如果物品i已放入揹包,則j=j-w[i];如果物品i未放入揹包,則j=j。

3、重複上述兩步判斷後續物品i到物品n-1是否放入揹包。

4、對於物品n,直接通過m[n][j]是否為0來判斷物品n是否放入揹包。

參考:五種常用演算法之三:動態規劃

#include

#include

#include

using

namespace

std;

stack

knapsack(int c,vector w,vector v,int &max_m)

} /*cout << "最優值矩陣:"

j=c;

for(i=0;i1;i++)

}

if(m[w.size()-1][j]!=0

)

return

res;

}int

main()

cout

<

物品重量:

"<

for(int i=0;i)

cout

cout

<

cout

<

輸入物品權重,以0結束

"<

while(1

)

cout

<

物品權重:

"<

for(int i=0;i)

cout

cout

<

result=knapsack(max_weight,weight,value,result_m);

cout

<

放入揹包的物品為:

"<

while(!result.empty())

cout

<

cout

<

揹包最大價值為:

01揹包問題 (動態規劃演算法)

0 1 揹包問題 給定 n 種物品和乙個容量為 c 的揹包,物品 i 的重量是 wi,其價值為 vi 問 應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?分析一波 面對每個物品,我們只有選擇拿取或者不拿兩種選擇,不能選擇裝入某物品的一部分,也不能裝入同一物品多次。解決辦法 宣告乙個 大...

01揹包問題 (動態規劃演算法)

題目 給定n種物品和乙個容量為v的揹包,物品i的體積是wi,其價值為ci。每種物品只有乙個 問 如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?面對每個物品,我們只有選擇放入或者不放入兩種選擇,每種物品只能放入一次。我們用之前同樣的思路來走一遍試試 假設只剩下最後一件物品,我們有兩種選擇 ...

動態規劃演算法之0 1揹包問題

我們首先來看一下問題 乙個旅行者有乙個容量為c的揹包,現在有n種物品,每件的重量分別是w1 w 2 w n,每件物品的價值分別為v1 v 2 v n,需要將物品放入揹包中,要怎麼樣放才能保證揹包中物品的總價值最大?具體資料如下表,其中n 4,c 8。前面已經對動態規劃的基本概念做了詳細的講解,動態規...