回溯演算法 01揹包問題

2021-10-02 07:45:11 字數 3225 閱讀 7876

假期 2020.01

.20

0-1揹包問題一般描述為:給定n種物品和乙個揹包。物品i的重量是w(i),其價值為v(i),揹包的容量為c。問應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大? 

注: 每個物品只能使用一次。

這次分析01揹包問題,採用回溯的方法實現。

簡單的來說,回溯就是採用dfs然後加上乙個復原的操作,即從初始狀態出發,然後按照深度優先遍歷的方法,根據約束條件進行搜尋。當發現當前節點滿足不了求解的條件的時候,就復原當前操作,嘗試其他途徑進行搜尋。常言道:「能進則進,進不了則換,換不了則退」。

解空間的大小

約束條件

結束條件

假設4個物品放入乙個容量為10的揹包,求最大價值。並且value[ ] = ,weight[ ] = ;

最開始應該判斷是否揹包能夠容納全部的物品,若能夠,直接輸出全部物品的價值和與全部物品序號即可。

if

(cw + weight[i]

<= total_size)

//當前重量小於揹包的最大容量

當第二步操作之後,因為我們需要求解的是最優解,那麼還需要乙個判斷函式,當物品 i 未放入時,剩下的物品全部放入時,是否會出現更加優的解,那麼增加以下函式:

int

bount_size

(int i)

if

(bount_size

(i +1)

> best_value)

根據儲存選擇的物品序號輸出方案即可。

#include

#include

using namespace std;

#define max_size 100

int count_size, total_size;

double cw =

0, cp =

0, best_value =0;

//當前揹包的物品重量,價值與當前最優值

int choice[max_size]

;//暫時選入物品序號

int best[max_size]

;//儲存最終選入的物品序號

double value[max_size]

, weight[max_size]

;void

re_search()

;//查詢函式

void

back_track

(int);

//搜尋函式

intbount_size

(int);

//判斷是否繼續查詢

intmain()

void

re_search()

//查詢函式

if(sum_weight < total_size)

else

cout << endl;

}return;}

void

back_track

(int i)

//搜尋函式

if(cw + weight[i]

<= total_size)

//當前重量小於揹包的最大容量if(

優化函式部分double bount_size(int i)

因為還可以借助餘下容量來減少需要判斷的物品是否應該算入最大值上界的計算中。

double

bount_size

(int i)

if(i < count_size)

//還剩下物品i時

val +

= value[i]

/ weight[i]

* weight_left;

return val + cp;

}

#include

#include

using namespace std;

#define max_size 100

int count_size, total_size;

double cw =

0, cp =

0, best_value =0;

//當前揹包的物品重量,價值與當前最優值

int choice[max_size]

;//暫時選入物品序號

int best[max_size]

;//儲存最終選入的物品序號

double value[max_size]

, weight[max_size]

;void

re_search()

;//查詢函式

void

back_track

(int);

//搜尋函式

double

bount_size

(int);

//判斷是否繼續查詢

intmain()

void

re_search()

//查詢函式

if(sum_weight < total_size)

else

cout << endl;

}return;}

void

back_track

(int i)

//搜尋函式

if(cw + weight[i]

<= total_size)

//當前重量小於揹包的最大容量if(

bount_size

(i +1)

> best_value)

return;}

double

bount_size

(int i)

if(i < count_size)

//還剩下物品i時

val +

= value[i]

/ weight[i]

* weight_left;

return val + cp;

}

回溯演算法 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揹包問題(回溯演算法實現)

問題描述 有n 件物品和乙個容量為c 的揹包。第i件物品的價值是v i 重量是w i 求解將哪些物品裝入揹包可使價值總和最大。所謂01揹包,表示每乙個物品只有乙個,要麼裝入,要麼不裝入。今天下午的演算法複習課,老師提的各種演算法經典問題時,出現頻率就是01揹包問題了!動態規劃 回溯法 分支限界法,在...

演算法 回溯法 0 1揹包問題

fishing pan 回溯法是一種非常有效的方法,有 通用的解題法 之稱。它有點像窮舉法,但是更帶有跳躍性和系統性,他可以系統性的搜尋乙個問題的所有的解和任一解。回溯法採用的是深度優先策略。回溯法解決問題一般分為三個步驟 1 針對所給問題,定義問題的解空間 2 確定易於搜尋的解空間結構 3 以深度...