01揹包問題(回溯演算法實現)

2021-06-14 20:35:35 字數 1351 閱讀 3004

問題描述:有n

件物品和乙個容量為c

的揹包。第i件物品的價值是v[i],重量是w[i]。求解將哪些物品裝入揹包可使價值總和最大。所謂01揹包,表示每乙個物品只有乙個,要麼裝入,要麼不裝入。

今天下午的演算法複習課,老師提的各種演算法經典問題時,出現頻率就是01揹包問題了!動態規劃、回溯法、分支限界法,在貪心演算法時也提到注意揹包問題,當然01揹包問題不能用貪心演算法實現,不能保證能得到最優解。回溯法是最近學的,所以試著用c語言將其實現了下,下面作以分析,後期將會繼續用其他兩種演算法實現01揹包問題,並做比較。

回溯法:01揹包屬於找最優解問題,用回溯法需要構造解的子集樹。在搜尋狀態空間樹時,只要左子節點是可乙個可行結點,搜尋就進入其左子樹。對於右子樹時,先計算上界函式,以判斷是否將其減去,剪枝啦啦!

上界函式bound():當前價值cw+剩餘容量可容納的最大價值<=當前最優價值bestp。

為了更好地計算和運用上界函式剪枝,選擇先將物品按照其單位重量價值從大到小排序,此後就按照順序考慮各個物品。

下面直接貼**吧:

#include

#include

int n;//物品數量

double c;//揹包容量

double v[100];//各個物品的價值

double w[100];//各個物品的重量

double cw = 0.0;//當前揹包重量

double cp = 0.0;//當前揹包中物品價值

double bestp = 0.0;//當前最優價值

double perp[100];//單位物品價值排序後

int order[100];//物品編號

int put[100];//設定是否裝入

//按單位價值排序

void knapsack()

if(cw+w[i]<=c)

if(bound(i+1)>bestp)//符合條件搜尋右子數

backtrack(i+1);

}//計算上界函式

double bound(int i)

if(i<=n)

b+=v[i]/w[i]*leftw;

returnb;

}int main()

knapsack();

backtrack(1);

printf("最有價值為:%lf\n",bestp);

printf("需要裝入的物品編號是:");

for(i=1;i<=n;i++)

return0;

}執行結果截圖:

演算法複雜度分析:上界函式bound()需要o(n)時間,在最壞的情況下有o(2^n)個右子結點需要計算上界,回溯演算法backtrack需要的計算時間為o(n2^n)。

回溯演算法 0 1揹包問題

給定乙個物品集合s 1,2,3,n 物品i的重量是wi,其價值是vi,揹包的容量為w,即最大載重量不超過w。在限定的總重量w內,我們如何選擇物品,才能使得物品的總價值最大。0 1揹包問題回溯演算法的資料結構 define num 100 int c 揹包的容量 int n 物品的數量 int cw ...

回溯演算法 01揹包問題

假期 2020.01 200 1揹包問題一般描述為 給定n種物品和乙個揹包。物品i的重量是w i 其價值為v i 揹包的容量為c。問應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?注 每個物品只能使用一次。這次分析01揹包問題,採用回溯的方法實現。簡單的來說,回溯就是採用dfs然後加上...

0 1揹包問題,回溯實現

0 1揹包 問題描述,noip 2001 裝箱問題 有乙個箱子容量為 v 正整數,0 v 20000 同時有 n個物品 0 n 30,每個物品有乙個體積 正整數 要求n 個物品中,任取若干個裝入箱內,使箱子的剩餘空間為最小。動態規劃考慮 容量為v的箱子,最多能裝多少單位體積的物品vmax,v vma...