0 1揹包問題(分支限界法)

2021-10-06 12:57:01 字數 3690 閱讀 5652

需求分析

0.問題描述

給定一揹包的容量c,和n個物品的重量wi價值vi,求在揹包容量允許的條件下能裝入的最大價值

1.問題分析

①解空間:子集樹,第i層每個節點有兩棵子樹:選擇物品i,不選擇物品i

②優先佇列的優先順序如何確定?

每個節點的祖先節點都已經確定,那麼可以得到已經裝入揹包的物品的價值,加上剩餘 物品能裝入揹包的最大價值,依此得到優先順序,即當前結點的「值」。

這裡用的是近似,剩餘的物品按照單位重量價值非公升序排序,將單位重量價值大的先放 入,放不

下整個物品的話,就放入一部分。

③剪枝:進入左子節點時,物品的重量小於剩餘揹包的容量;進入右子結點時,要滿足 上界約束。進入乙個子結點就把它加入優先佇列。

上界約束:當前結點的「值」比最優解的值要大。

2.輸入資料

輸入揹包的容量,物品的重量和價值

3.輸出資料

輸出能裝入揹包的最大價值

4.測試樣例設計

演算法設計與分析1.演算法的基本思想變成了非層次遍歷

比如:第一層根結點,左右子結點都滿足條件,加入佇列;右結點優先順序比較高

處理根節點的右結點,它的左右子結點都可以加入,現在佇列裡面有它父結點的左子結點和它的兩個子節點,其中它的左子結點優先順序比較高

處理根節點的右子結點的左子結點,兩個子節點都可以加入……

基本思想:

①輸入的物品重新排序,按照單位重量價值降序排序

②在乙個優先佇列裡面儲存目前待處理的結點,取出的隊首元素是值最大的,目前最有 可能成為最優解路徑的一部分。

③不斷取出隊首元素進行處理,考察其左右子結點,滿足條件加入優先佇列

④不斷重複以上③步驟,直到處理的結點是葉子結點,那麼它到根節點的路徑一定是最 優解。

2.輸入和輸出的格式

從檔案輸入,輸出到檔案。

有多組輸入,每組資料第一行是揹包的容量c,和物品的件數n,接下來的n行第i行 是物品i的重量,物品i的價值。

3.演算法的具體步驟

4.演算法的時空分析

①空間複雜性:限界函式為o(1),最壞情況下需搜尋2^(n +1) –2個節點,需o(2^n ) 個空間儲存節點,則演算法空間複雜性為o(2^n )。

②時間複雜性:限界函式時間複雜度為o(n),而最壞情況有2^(n +1) – 2個節點,若 對每個節點用限界函式判斷,則其時間複雜度為o(n2^n).而演算法中時間複雜度主要依賴 限界函式,則演算法的時間複雜度為o(n2^n)。

、測試結果

全部**:

#include #include #include using namespace std;

class object

;class maxheapqnode

;//建立優先佇列時使用的

struct cmp

};//用於預處理的重排

bool compare(const object &a, const object &b)

int n;//物品件數

int c;//揹包容量

int cw;//當前重量

int cp;//當前解

int bestp;//最優解的值

object obj[100];//物品集合

int bestx[100];//最優解的物品集合

ifstream in("input.txt");

ofstream out("output.txt");

//上界函式

int bound(int i)

if(i <= n)

return tmp_cp;

}//新增節點到優先佇列

void addalivenode(priority_queue, cmp> &q, maxheapqnode *e, int up, int wt, int curp, int i, int ch)

//分支限界法求解

void maxknapsack()

//右子結點,如果可能產生最優解,可以加入

up = bound(i + 1);

if(up >= bestp) //(注意這裡必須是大於等於)

//取出隊首結點給下一次迴圈來處理

e = q.top();

q.pop();

cw = e->weight;//(結點的重量)

cp = e->profit;//(結點的價值)

up = e->upprofit;//(結點的值)

i = e->lev;//(結點的層次)

}//構造最優解的物品集合

for(int j = n; j > 0; --j)

}//輸入&&預處理

int input()

//重排

sort(obj + 1, obj + n + 1, compare);

return 1;

} return 0;

}//輸出

void output()

int main()

in.close();

out.close();

return 0;

}

0 1揹包問題 分支限界法

0 1揹包問題可描述為 n個物體和乙個揹包。對物體i,其價值為value,重量為weight,揹包的容量為w 如何選取物品裝入揹包,使揹包中所裝入的物品總價值最大?2.1 用到的資料結構 class goods 定義貨物資料型別 class knapsack 揹包 2.2 演算法步驟1 定 空間。x...

分支限界法 0 1揹包問題

分支限界法類似於回溯法,也是在問題的解空間上搜尋問題解的演算法。一般情況下,分支限界法與回溯法的求解目標不同。回溯法的求解目標是找出解空間中滿足約束條件的所有解,而分支限界法的求解目標則是找出滿足約束條件的乙個解,或是在滿足約束條件的解中找出使某一目標函式值達到極大或極小的解,即在某種意義下的最優解...

分支限界法01揹包問題 01揹包問題

1.01揹包問題的描述 有n個不可分割的物品,它們有各自的重量和價值,現有固定容量的揹包,選擇把哪些物品放入揹包可以讓揹包中物品的價值最大。2.錯覺 按照價值和重量的比值 價效比 進行排序,依次嘗試放入直到放不進揹包為止。但是細想思考一下就能發現,這個貪心演算法是有問題的,看下面乙個例子。揹包容量1...