東 華 大 學
《算法設計分析與綜合實踐》分析題作業
學生姓名: 曹晨 學號:171310402
請勿轉載或抄襲
-
作業題目
二維0-1背包問題
給定n種物品和一背包,物品i的重量是wi,體積是bi,其價值為vi,背包的容量為c,容積為d。問應如何選擇裝入背包的物品,使得裝入背包中的物品總價值最大?在選擇裝入背包的物品時,對每種物品i只有兩種選擇,即裝入背包和不裝入背包。不能將物品i裝入背包多次,也不能只裝入部分的物品i。試設計一個解決問題的動態規划算法,並分析算法的計算復雜性。
- 解題過程(針對算法設計題)
-
解題思路或算法設計思路。
這個問題和一維的背包問題類似,同樣具有最優子結構性質,只需將二維數組變成三維數組來考慮兩個變量的情況下的解法。其子問題的最優值為m[i][j][h],即背包容量為j,容積為h,可選擇的物品為i,i+1,…,n時背包問題的最優值。由背包的最優子結構可以建立計算m[i][j][h],即m[i][j][h]=max(m[i-1][j][h],m[i-1][j-w[i-1]][h-b[i-1]]+v[i-1]);按照這個遞歸可以算出m(n,c,d)的最優值。
-
算法描述
算法描述如下:
//用於計算最優值的函數
1 int Knapsack(int c,int d,int***m,int *v,int w*){
2 for(i=1 to n)
3 for(j=0 to c)
4 for(h=0 to d)//三重循環遍歷當容積為h容量為j時前0-i個物品的最優值
5 if(h>=b[0]&&j>=w[0])
6 m[i][j][h]=max(m[i-1][j][h],m[i-1][j-w[i-1]][h-b[i-1]]+v[i-1]);
7 for(i=1 to n)//遍歷數組,找到最大值即為最大價值數
8 maxo=max(maxo,m[i][c][d])
9 return maxo
10 }
//用於求具體放入哪些物品時的函數
1 void Traceback(int ***m,int c,int d,int n)
2 {
3 for(i=n to 1)//遍歷數組,反過來求最優解時裝入的物品。
4 if( if(m[i][c][d]==m[i-1][c][d]))
5 x[i-1]=0;
6 else{
7 x[i-1]=1;
8 c=c-w[i-1];
9 d=d-b[i-1]
10 }//當第i件物品和第i-1件物品(容量和容積均減去第i件物品對應的指數)的最優解值相同時,沒放入,否則放入背包里了
11 x[0]=(m[0][c][d])?1:0;//第一件物品沒法和上一件比,當此時容積和容量的大小有一個小於到第一個物品的體積和重量,則第一個沒放入
12 }
輸入:
個數:5
容量:8
容積:7
5個物品的重量、體積和價值:
3 2 6
4 1 5
6 4 7
1 1 3
2 4 8
輸出:
最大價值為:17
三個物品分別是:
3 6 2
1 3 1
2 8 4
- 算法分析:
時間復雜度:
用了三個疊套的for循環來尋找子問題的最優解,用了一個for循環來求最大值,一個for循環來求最優解時放入背包的物品,一個for循環來輸出放入的物品。
f(n)=ncd+n+n+n=ncd+3n=O(ncd);
空間復雜度:
由於采用了三位數組來存儲子問題的最優解,三個一維數組來存儲每個物品的重量體積和價值,一個一維數組來存儲在最優解時是否放入背包
f(n)=ncd+n+n+n+n=ncd+4n=O(ncd);