動態規劃和樹搜索算法求解0-1揹包問題
問題背景
給定n
種物品和一個揹包,物品i的重量是wi
,價值vi
, 揹包承重爲C
, 問如何選擇裝入揹包的物品,對於每種物品只能選擇完全裝入或不裝入,一個物品至多裝入一次,使裝入揹包中的物品的總價值最大?
問題抽象及要求
要求: 使用基於動態規劃的算法和樹搜索算法求解0-1揹包問題,並比較二者在不同輸入上的時間開銷。
數據格式:C|w[1],v[1]|….|w[n],v[n]
。
(請描述算法執行過程,寫出完整的僞代碼。注意測試時間開銷時應去除從文件中讀入數據的時間。)
描述動態規劃方法求解0/1揹包問題
由於優化子結構和重疊子問題的證明、遞歸方程的構造在課件中已經呈現出來了,在此就不再贅述。
該算法的運行流程大致如下:
i. 首先,算法的第1行到第4行先求解邊界條件,將矩陣的第n行的結果先求解出來。
ii. 然後,算法的第5行到第9行求解矩陣的第2行到第n-1行的結果。
iii. 最後,算法的第10行到第11行求解矩陣的第1行的邊界條件。
描述動態規劃方法構造0/1揹包問題優化解
描述樹搜索算法求解0/1揹包問題
算法的部分描述在課件中已經給出,再次就不再贅述。
二叉搜索樹的每個結點記錄以下信息:當前裝入揹包中物品的總重量w、當前裝入揹包中物品的總價值v、此時揹包能夠容納的物品的價值上界UB、左節點left、右節點right、雙親結點parent。
首先按照價值重量比降序排列n個物品和對應的價值。
然後初始化根節點,使根節點的w爲0,v爲0,UB爲C。
由於對於第i層結點,如果r.left.w>C,此時裝入揹包中物品的總重量大於揹包能承受的總重量,那麼停止搜索r結點的左邊分支。如果UB小於當前優化解的下界,說明當前的優化解不需要更新,就停止搜索這一個分支。否則,優先選擇UB大的結點,繼續爬山搜索。
動態規劃方法求解0/1揹包問題優化解的算法僞代碼
Knapsack(m)
For j←0 To min(w_n-1,C) Do
m[n,j]=0;
For j←w_n To C Do
m[n,j]=v_n;
For i←n-1 To 2 Do
For j←0 To w_i-1 Do
m[i,j]=m[i+1,j];
For j←w_i To C Do
m[i,j]=max{m[i+1,j],m[i+1,j-w_i ]+v_i };
If C<w_i Then m[1,c]=m[2,c];
Else m[1,C]=max{m[2,C],m[2,j-w_1 ]+v_1 };
動態規劃方法構造0/1揹包問題優化解的算法僞代碼
Construct-knapsack(m,n,c)
If m(1,c)==m(2,c)
x[1]←0;
Else x[1]←1;
For a←2 To n-1 Do
If x[a-1]==1
c←c-w_(a-1);
If m(a,c)==m(a+1,c)
x[a]←0;
Else x[a]←1;
Else if x[a-1]==0
If m(a,c)==m(a+1,c)
x[a]←0;
Else x[a]←1;
If c≥w_n Then
x[n]←1;
Else x[n]←0;
Print x;
樹搜索算法求解0/1揹包問題的僞代碼
runSearchTree()
r.w←w_0;
r.v←v_0;
r.UB←r.v+(C-r.w)*v_1/w_1 ;
searchTree(r,0,0);
searchTree(r,i,DB)
If i+1<n
r.left.w←r.w+w_(i+1);
r.left.v←r.v+v_(i+1);
r.left.UB←r.left.v+(C-r.left.w)*v_(i+2)/w_(i+2);
r.left.parent = r;
r.right.w←r.w;
r.right.v←r.v;
r.right.UB←r.right.v+(C-r.w)*v_(i+2)/w_(i+2);
r.right.parent = r;
If r.left.w>C
x_(i+1)←0;
DB=getBestValue();
searchTree(r.right,i + 1,DB);
Else if r.UB<DB
x_i←0;
searchTree(r.parent.right,i,DB);
Else Do
If r.left.UB≥ r.right.UB
x_(i+1)←1;
DB=getBestValue();
searchTree(r.left,i + 1,DB);
Else Do
x_(i+1)←0;
DB=getBestValue();
searchTree(r.right,i + 1,DB);
運行結果
結果分析
動態規劃方法求解0/1揹包問題的結果分析
構造優化解算法的時間複雜性T(n)=O(Cn)=O(Cn)+O(n)
,這是一個僞多項式算法。如果C=2^n
,
那麼
構造優化解算法的空間複雜性爲O(Cn)
。
求解優化解算法的時間複雜性T(n)= O(n)
。
求解優化解算法的空間複雜性爲O(Cn)
。
樹搜索算法求解0/1揹包問題的結果分析
根據以上截圖的結果,我們可以看到,根據測試用例,揹包能承受的最大重量是:64248,最大價值是:851。由於對物品進行了排序,所以選中的揹包和測試用例輸入的順序不太一樣。
除此之外,樹搜索算法所花費的時間要比動態規劃算法花費的時間要少一個數量級或者以上。由此可見,這個兩個算法的時間複雜度相差還是相當大的。