一.分支限界法概述
(1)分支限界法就是採用廣度優先的策略,依次搜尋活結點所有的分枝,也就額是所有的相鄰結點。在求最優解時採用乙個限界函式,計算限界函式值,選擇乙個最有利的子節點作為擴充套件結點,使搜尋樹朝著解空間樹上有最優解的分支推進,以便盡快找出乙個最優解。
(2)常見的兩種分支限界法
先進先出(fifo)佇列式:在先進先出的分支限界法中,用佇列作為組織活結點表的資料結構,並按照佇列先進先出的原則選擇結點作為擴充套件結點。
優先佇列(pq):用優先佇列作為組織活結點表的資料結構。
二.0-1揹包問題
問題:給定n種物品和一揹包。物品i的重量是wi,其價值為pi,揹包的容量為c。問應如何選擇裝入揹包的物品,使得裝入揹包中物品的總價值最大?
#include#includeusing
namespace
std;
const
int maxn=99
; int
n,c;
intw[maxn];
intv[maxn];
int bestv=0
;int
bestx[maxn];
int total=1; //
解空間中的節點數累計,全域性變數
struct nodetype //
佇列中的結點型別
;void
input()
cout
<
請輸入揹包的容量:
"<
cin>>c;
}void bound(nodetype &e) //
計算分支結點e的上界
if(i<=n) //
餘下物品只能部分裝入
e.ub=sumv+(c-sumw)*v[i]/w[i];
else e.ub=sumv;
} void enqueue(nodetype e,queue&qu)
//結點e進隊qu
}else qu.push(e); //
非葉子結點進隊
} void
bfs()
e2.no=total++;
e2.i=e.i+1
; e2.w=e.w;
e2.v=e.v;
for(j=1;j<=n;j++)
e2.x[j]=e.x[j];
e2.x[e2.i]=0
; bound(e2);
if(e2.ub>bestv) //
若右孩子結點可行,則進隊,否則被剪枝
enqueue(e2,qu);
}} void
output()
intmain()
0 1揹包問題 分支限界法 優先佇列分支限界法
演算法首先根據基於可行結點相應的子樹最大價值上界優先順序,從堆中選擇乙個節點 根節點 作為當前可擴充套件結點。檢查當前擴充套件結點的左兒子結點的可行性。如果左兒子結點是可行結點,則將它加入到子集樹和活結點優先佇列中。當前擴充套件結點的右兒子結點一定是可行結點,僅當右兒子結點滿足上界函式約束時,才將它...
0 1揹包問題 分支限界法
0 1揹包問題可描述為 n個物體和乙個揹包。對物體i,其價值為value,重量為weight,揹包的容量為w 如何選取物品裝入揹包,使揹包中所裝入的物品總價值最大?2.1 用到的資料結構 class goods 定義貨物資料型別 class knapsack 揹包 2.2 演算法步驟1 定 空間。x...
分支限界法 0 1揹包問題
分支限界法類似於回溯法,也是在問題的解空間上搜尋問題解的演算法。一般情況下,分支限界法與回溯法的求解目標不同。回溯法的求解目標是找出解空間中滿足約束條件的所有解,而分支限界法的求解目標則是找出滿足約束條件的乙個解,或是在滿足約束條件的解中找出使某一目標函式值達到極大或極小的解,即在某種意義下的最優解...