演算法設計與分析 0 1揹包的多種求法

2021-06-29 08:32:18 字數 2503 閱讀 6976

整數揹包問題即0/1揹包問題。對每種物品或者全取或者一點都不取,不允許只取一部分。現有n種物品,對1<=i<=n,已知第i種物品的重量為正整數wi,價值為正整數vi,揹包能承受的最大載重量為正整數w,現要求找出這n種物品的乙個子集,使得子集中物品的總重量不超過w且總價值盡量大。

窮舉法:

求解整數揹包問題的窮舉演算法,用窮舉法解決0-1揹包問題,需要考慮給定n個物品集合的所有子集,找出所有可能的子集(總重量不超過揹包重量的子集),計算每個子集的總重量,然後在他們中找到價值最大的子集。考慮給定n個物品集合的所有子集,找出所有可能的子集(總重量不超過揹包重量的子集),計算每個子集的總重量,然後在他們中找到價值最大的子集。 

#include #include using namespace std;

class packenum

//獲取揹包內物品的最大值

int getbestvalue() const

//儲存最優解

if(currentweight <=m_c

&& bestvalue < currentvalue)

}return bestvalue;

}};int main(void)

動態規劃法:

0-1揹包問題可以看作是尋找乙個序列,對任乙個變數 的判斷是決定=1還是=0.在判斷完之後,已經確定了,在判斷時,會有兩種情況:

(1) 揹包容量不足以裝入物品i,則=0,揹包的價值不增加;

(2) 揹包的容量可以裝下物品i,則=1,揹包的價值增加。

這兩種情況下揹包的總價值的最大者應該是對判斷後的價值。

令表示在前i個物品中能夠裝入容量為j的揹包的物品的總價值,則可以得到如下的動態規劃函

數:

#include #include using namespace std;

int c[30][100];//表示把前i個物品裝入容量為j的揹包中獲得的最大價值

int x[30]; //存放揹包的選擇情況

int knapsack(int w,int v,int m,int n)

else

c[i][j]=c[i-1][j];

} //求裝入揹包的物品

j=m;

for(i=n;i>0;i--)

else

x[i]=0;

} return(c[n][m]);//返回揹包取得的最大價值

}int main()

{ int m;//存放揹包容量

int n;//存放物品數量

int i,j;

int w[100];//存放重量

int v[100];//存放價值

cout

cout << "請輸入揹包的容量" << endl;

cin >>m;

cout>v[i];

cout<

回溯法:

分枝界限可以說是dfs

和bfs

的結合,綜合了

dfs演算法空間複雜度低和

bfs時間複雜度低的優點。分枝界限法在回溯法的基礎上更進了一步,在回溯法中, 一旦從問題狀態空間樹匯出的解不滿足約束函式,我們就將其分枝剪掉。在處理此類問題時,回溯法的思想可以進一步強化。在回溯法的基礎上加上兩個額外的條件 就變成了分支界限法

1.  對於一棵狀態空間樹的每乙個結點所代表的部分解, 我們要提供一種演算法,計算出通過這個部分解所繁衍也的任何解在目標函式上的最佳邊界。

2. 目前所求得的最佳解

有了這兩個條件,我們可以用當前求得的最佳解和所有結點的最佳邊界比較,如果某結點的最佳邊界不能超越當前最佳解(在求最大化問題中,該結點的最佳上界不大於當前最佳解,在求最小化問題中,該結點的最佳下界不小於當前最佳解),則將其剪掉。這就是分枝界限的主要相思。

各種演算法在解揹包問題時的比較如下表所示:

演算法名稱

時間複雜度 優點

缺點 改進

窮舉法最優解

速度慢 剪枝

動態規劃法

最優解速度慢

遞迴方程求解

回溯法最優解

速度慢改進剪枝

分枝限界法

最優解速度慢

優化限界函式

揹包問題是np完全問題。半個多世紀以來,該問題一直是演算法與複雜性研究的熱門話題。通過對0-1揹包問題的演算法研究可以看出,回溯法和分枝限界法等可以得到問題的最優解,可是計算時間太慢;動態規劃法也可以得到最優解,當時,演算法需要的計算時間,這與回溯法存在一樣的缺點——計算速度慢;採用貪心演算法,雖然耗費上優於前者,但是不一定是最優解。在本次報告中參考了許多文獻,自己對於動態規劃、回溯、分支限界有了更深的了解。通過本次試驗,了解了時空複雜度對演算法的影響。對時間和空間在計算機中的權衡有了進一步的了解。同時對於演算法的理解不斷加深,在程式編寫中可以將幾個相關的演算法混合使用,採用它們各自的優點。在上面的回溯法中結合bfs和dfs在時間和空間上的優點,改進而來。

演算法設計與分析 0 1揹包問題

問題描述 給定n個重量為,價值為的物品和乙個容量為c的揹包,0 1揹包問題是求這些物品中的乙個 最有價值的子集,並且能夠裝入揹包中。基本演算法思想 暴力法 用暴力法解決0 1揹包問題,需要考慮給定n個物品集合的所有子集,找出所有重量不超過揹包重量的子集,計算其每個子集的 總價值,比較輸出價值最大的那...

演算法分析與設計 蠻力法0 1揹包

蠻力法是一種簡單直接解決問題的方法,常常直接基於問題的描述,所以蠻力法也是最容易應用的方法。蠻力法所依賴 的基本技術是遍歷,即採用一定的策略依次處理待求解問題的所有元素,從而找出問題的解。由於其需要依次窮舉待處理的元素,因此蠻力法是一種典型的指數級時間演算法。給定n個重量為 價值為的物品和乙個容量為...

演算法設計與分析 蠻力法求解0 1揹包問題

由於最近在複習演算法設計與分析,所以就想試著完成一下書上的 描述 揹包問題 給定重量分別為,價值分別為的n件物品,和乙個承重為w的揹包。求這些物品中乙個最有價值的子集,並能裝到揹包中。揹包問題的蠻力解法是窮舉這些物品的所有子集,找出能夠裝到揹包中的所有子集,並在這些子集中找出價值最大的子集 實驗資料...