0 1揹包 回溯法

2021-09-06 06:34:32 字數 1736 閱讀 6346

演算法描述:

0-1揹包的回溯法,與裝載問題的回溯法十分相似。在搜尋解空間樹時,只要其左兒子結點是乙個可行結點,搜尋就進入其左子樹。當右子樹中有可能包含最優解時才進入右子樹進行搜尋。否則將右子樹剪去。

計算右子樹上界的更好演算法是:

將剩餘物品依其單位重量價值排序,然後依次裝入物品,直至裝不下時,再裝入該物品的一部分而裝滿揹包。

演算法實現:

由bound函式計算當前節點處的上界。

類knap的資料成員記錄解空間樹的節點資訊,以減少引數傳遞及遞迴呼叫所需的棧空間。

在解空間樹的當前擴充套件結點處,僅當要進入右子樹時,才計算上界bound,以判斷是否可將右子樹剪去。

進入左子樹時不需要計算上界,因為它與其父節點的上界相同。

演算法實現:(**有點小問題,正在修改中)

#include #include 

#include

using

namespace

std;

template

class

knap;

template

void knap::backtrack(int

i)

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

進入左子樹

if(bound(i+1)>bestp)//

進入右子樹

backtrack(i+1);}

template

typep knap

::bound(int i)//

計算上界

//裝滿揹包

if(i<=n)

b+=p[i]*cleft/w[i];

returnb;}

class

object

private

:

intid;

float

d;};

int compare (const

void * a, const

void *b)

template

typep knapsack(typep p,typew w,typew c,

intn)

if(w<=c)

return p;//

裝入所有物品

//依物品單位重量價值排序

qsort (q,n, sizeof(int

), compare);

knap

k; k.p = new typep [n+1

]; k.w = new typew [n+1

];

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

k.cp = 0

; k.cw = 0

; k.n =n;

k.bestp = 0

; k.backtrack(1);

//coutdelete k.w;

delete k.p;

return

k.bestp;

}int

main()

;

int w[4]= ;

int num = knapsack(p,w,7,4

); cout

return0;

}

01揹包回溯法

計算機演算法基礎 第三版 余祥宣 崔國華 等 華中科技大學出版社 中回溯法解決01揹包問題 演算法思想 基於貪心演算法的回溯演算法 w p陣列是按照效益p w拍好序的陣列 include const int n 8 物品個數 const int m 110 int w n 1 重量陣列,從1開始 i...

0 1揹包(回溯法)

描述 需對容量為c 的揹包進行裝載。從n 個物品中選取裝入揹包的物品,每件物品i 的重量為wi 價值為pi 對於可行的揹包裝載,揹包中物品的總重量不能超過揹包的容量,最佳裝載是指所裝入的物品價值最高。輸入 多個測例,每個測例的輸入佔三行。第一行兩個整數 n n 10 和c,第二行n個整數分別是w1到...

0 1揹包 回溯法

include include include using namespace std define n 100000 int n,c int cp 0,cw 0,bestp 0 cp是當前價值,cw是當前重量,bestp是當前最優值。int w n p n x n bestx n bestx陣列是...