01揹包問題(用c語言實現) 回溯法求解

2021-08-01 08:34:59 字數 1796 閱讀 4922

回溯法求解01揹包

用回溯法解問題時,應明確定義問題的解空間。問題的解空間至少應包含問題的乙個(最優)解。例如,對於有n種可選擇物品的0-1揹包問題,其解空間由長度為n的0-1向量組成。該解空間包含對變數的所有可能的0-1賦值。當n=3時,其解空間是 定義了問題的解空間後,還應將解空間很好的組織起來,使得能用回溯法方便地搜尋整個解空間。通常將解空間組織成樹或圖的形式。

例如,對於n=3時的0-1揹包問題,可用一棵完全二叉樹表示其解空間,如圖5-1所示。

解空間樹的第i層到第i+1層表上的標號給出了變數的值。從樹根到葉的任一路徑表示解空間中的乙個元素。例如,從根節點到節點h的路徑相應於解空間中的元素(1,1,1)。

確定了解空間的組織結構後,回溯法送開始節點(根節點)出發,以深度優先方式搜尋整個解空間。這個考試節點成為活結點,同時也成為當前的擴充套件節點。在當前的擴充套件結點處,搜尋向縱深方向移至乙個新節點。這個新節點就成為新的活結點,並成為當前擴充套件節點,如果在當前的擴充套件節點處不能退再向縱深方向移動,則當前擴充套件節點就成為死節點。此時,應往回移動至最近的乙個活結點處,並使這個活結點成為當前的擴充套件節點。回溯法以這種工作方式遞迴的在解空間中搜尋,直至找到所要求的結果解空間中已無活結點為止。

例如,對於n=3時的0-1揹包問題,考慮下面的具體例項:w=【16,15,15】,p=【45,25,25】,c=30。從圖5-1的根節點開始搜尋其解空間。開始時,根節點時唯一的活結點,也是當前的擴充套件節點。在這個擴充套件節點處,可以沿縱深方向移至節點b或者節點c。假設選擇先移至節點b。此時,節點a和節點b時活結點,節點b成為當前擴充套件節點。由於選取了w1,股災節點b處剩餘揹包容量是r=14,獲得的價值為45.從節點b處,可以移至節點d處或e。由於移至節點d至少需要w2=15的揹包容量,而現在僅有的揹包容量是r=14,故移至節點d導致不可行解。搜尋至節點e不需要揹包容量,因而是可行的。從而選擇移至節點e。此時,e成為新的擴充套件節點,節點a,b和e是活結點。在節點e處,r=14,獲取的價值為45.從節點e處,可以向縱深移至節點j或節點k。移至節點j導致不可行解,而移向節點k是可行的,於是移向節點k,它成為新的擴充套件節點。由於節點k是葉節點,故可得到乙個可行解。這個解相應的價值為45。xi的取值由根節點到葉節點k的路徑唯一確定,即x=(1,0,0)。由於在節點k處已不能再向縱深擴充套件,所以節點k成為死節點。在返回到節點e處。此時在節點e處也沒有可擴充套件的節點,它也成為死節點。

#include#define max 100

int weight[max];

int value[max];

int n,max_weight,max_value;

int best_answer[max],answer[max];

void print()

void dfs(int level,int current_weight,int current_value)

} else

dfs(level+1,current_weight,current_value); }}

void init()

int main()

return 0; }

/* 3 30

16 15 15

45 25 25

5 10

2 2 6 5 4

6 3 5 4 6

*/

回溯法 0 1揹包問題(C 實現)

概念 回溯法是一種非常有效的方法,有 通用的解題法 之稱。它有點像窮舉法,但是更帶有跳躍性和系統性,他可以系統性的搜尋乙個問題的所有的解和任一解。回溯法採用的是深度優先策略。三個步驟 針對所給問題,定義問題的解空間 確定易於搜尋的解空間結構 以深度優先的方式搜尋解空間。優化方法 搜尋過程使用剪枝函式...

回溯法 0 1揹包問題

0 1揹包問題 給定n種物品和一揹包.物品i的重量是wi,其價值為ui,揹包的容量為c.問如何選擇裝入揹包的物品,使得裝入揹包中物品的總價值最大?分析 0 1揹包是子集合選取問題,一般情況下0 1揹包是個np問題.第一步 確定解空間 裝入哪幾種物品 第二步 確定易於搜尋的解空間結構 可以用陣列p,w...

0 1揹包問題 回溯法

0 1揹包問題 回溯法 一 專案描述 每種物品只有2 種選擇,分別為 裝入揹包或不裝入揹包,物品數和揹包容量已給定,計算裝入揹包物品的最大價值和最優裝入方案,用回溯法搜尋子集樹的演算法進行求解。二 演算法設計 a.物品有n種,揹包容量為c,分別用p i 和w i 儲存第i種物品的價值和重量,用x i...