回溯法解決0 1揹包問題

2022-05-11 17:58:45 字數 1433 閱讀 8205

問題描述:

有n件物品和乙個容量為

c的揹包。第

i件物品的價值是

v[i],重量是

w[i]。求解將哪些物品裝入揹包可使價值總和最大。

所謂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()

}}//

回溯函式

void backtrack(int

i)

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;}

intmain()

knapsack();

backtrack(1);

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

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

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

return 0;

}

時間複雜度分析:

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

回溯法解決0 1揹包問題

1.回溯法可以看作是窮舉法的一種實現方式 2.基本過程 每一步只生成解的一部分 部分解 並立即對該部分解進行評估,若有可能擴充套件成為 所求解 則繼續擴充套件,得到新的部分解,泛指嘗試其他部分解,知道窮盡所有可能.3.解空間 所有的可能的解的集合 解空間樹 將解空間組織成樹形成的樹形結構 常見的解空...

回溯法解決01揹包問題

一 問題描述 有n 個物品,它們有各自的重量和價值,現有給定容量的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?二 總體思路 因為回溯求解的規則是 後進先出 所以要用棧來存放符合條件的解,在儲存過程中用陣列來存放各個物品的體積和價值,然後用深度優先搜尋的方式求解,最後得到符合條件的最優解並輸出。三...

回溯法解決0 1揹包問題

0 1揹包問題指的是有乙個能裝w重的揹包,和n個不同重量的物體,如何選擇物體才能盡可能地裝滿揹包。public int maxw integer.min value 儲存揹包中物品總重量的最大值 cw表示當前已經裝進去的物品的重量和 i表示考察到哪個物品了 w揹包重量 items表示每個物品的重量 ...