整數揹包問題即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的揹包。求這些物品中乙個最有價值的子集,並能裝到揹包中。揹包問題的蠻力解法是窮舉這些物品的所有子集,找出能夠裝到揹包中的所有子集,並在這些子集中找出價值最大的子集 實驗資料...