第7章 分支限界演算法

2021-09-29 05:36:59 字數 3772 閱讀 1641

分支限界法類似於回溯法,是一種在問題的解空間樹上搜尋問題解的演算法。

分支限界法的求解目標則是找出滿足約束條件的乙個解,或是在滿足約束條件的解中找出使某一目標函式值達到極大或極小的解,即在某種意義下的最優解。

分支限界法常以廣度優先的方式搜尋問題的解空間樹。

在分支限界法中,每乙個活結點只有一次機會成為擴充套件結點。

活結點一旦成為擴充套件結點,就一次性產生其所有兒子結點。在這些兒子結點中,導致不可行解或導致非最優解的兒子結點被捨棄,其餘兒子結點被加入活結點表中。

此後,從活結點表中取下一結點成為當前擴充套件結點,並重複上述結點擴充套件過程。這個過程一直持續到找到所需的解或活結點表為空時為止。

從活結點表中選擇下一擴充套件結點的不同方式導致不同的分支限界法:

佇列式(fifo)分支限界法:按照佇列先進先出(fifo)原則選取下乙個節點為擴充套件節點。

優先佇列式分支限界法:按照優先佇列中規定的優先順序選取優先順序最高的節點成為當前擴充套件節點。

最大優先佇列:使用最大堆,體現最大效益優先

最小優先佇列:使用最小堆,體現最小費用優先

從活結點表中選擇下乙個活結點作為新的擴充套件結點,分支限界演算法通常可以分為兩種形式:

fifo(first in first out)分支限界演算法

按照先進先出(fifo)原則選擇下乙個活結點作為擴充套件結點,即從活結點表中取出結點的順序與加入結點的順序相同。

優先佇列分支限界演算法

在這種情況下,每個結點都有乙個耗費或收益。

根據問題的需要,可能是要查詢乙個具有最小耗費的解,或者是查詢乙個具有最大收益的解。

利用約束函式和限界函式剪去無效的分支,提高搜尋效率。

求解最大值問題時:

維護乙個活節點表,從活結點表中選擇乙個結對作為擴充套件節點

對擴充套件節點的每個分支,計算器上界值bound(i).

如果當前最大目標函式值bestc>=bound(i),那麼結點 i 就不會放入活結點表中個,否則放入。從而完成剪枝操作。

【例】一矩形陣列由數字0到9組成,數字1到9代表細胞,細胞的定義為沿細胞數字上下左右還是細胞數字則為同一細胞,求給定矩形陣列的細胞個數。如:

陣列4 10

0234500067

1034560500

2045600671

0000000089

有4個細胞。

【演算法分析】

⑴從檔案中讀入m*n矩陣陣列,將其轉換為boolean矩陣存入bz陣列中;

⑵沿bz陣列矩陣從上到下,從左到右,找到遇到的第乙個細胞;

⑶將細胞的位置入隊h,並沿其上、下、左、右四個方向上的細胞位置入隊,入隊後的位置bz陣列置為false;

⑷將h隊的隊頭出隊,沿其上、下、左、右四個方向上的細胞位置入隊,入隊後的位置bz陣列置為false;

⑸重複4,直至h隊空為止,則此時找出了乙個細胞;

⑹重複2,直至矩陣找不到細胞;

⑺輸出找到的細胞數。

【參考程式】

#include

using

namespace std;

int dx[4]

=,// x,y 方向上的增量

dy[4]

=;int bz[

100]

[100

],num=

0,n,m;

//二維陣列,儲存原始矩陣

void

doit

(int p,

int q)

//本方向搜尋到細胞就入隊}}

while

(t;//直至隊空為止

}int

main()

for(i=

0;i<=m-

1;i++

)for

(j=0

;j<=n-

1;j++)if

(bz[i]

[j])

doit

(i,j)

;//在矩陣中尋找細胞

(1)旅行商問題優先佇列式分支限界演算法的資料結構

#define inf 1000000 //∞

#define num 100

int n; //圖g的頂點數

int a[num][num]; //圖g的鄰接矩陣

int noedge = inf; //圖g的無邊標誌

int cc; //當前費用(子路的長度)

int bestc; //當前的最小費用(完整路的長度)

定義優先佇列

priority_queue h;

int minout[num]

;//各個頂點的最小出邊費用

int minsum =0;

//最小出邊費用之和

//計算各個頂點的最小出邊費用

int i, j;

for(i=

1; i<=n; i++

)初始化

node e;

for(i=

1; i<=n; i++

)  e.x[i]

= i;

e.s =1;

e.cc =0;

e.rcost = minsum;

int bestc = noedge;

搜尋排列樹

while

(e.s

else

delete

e.x;

//捨棄擴充套件結點

}else

}//完成結點擴充套件

delete

e.x;

}//隊列為空時,搜尋結束

if(h.

empty()

)break

;else}if

(bestc==noedge)

return noedge;

//表示無迴路

//輸出最優解

for(i=

1; i<=n; i++

)printf

("%d "

, e.x[i]);

printf

("\n");

//清空剩餘的佇列元素

while

(!h.

empty()

) h.

pop();

return bestc;

//返回最優解

分支限界演算法。

分支限界法類似於回溯演算法,是在問題的解空間樹上搜尋問題解的演算法,主要體現在兩點不同 1.求解目標不同。回溯演算法的求解目標是找出解空間樹中滿足約束條件的所有解,而分支限界法的求解目標是找出滿足約束條件的乙個解,或者是在滿足約束條件的解中找出某種意義下的最優解。搜尋解空間樹的方式不同。回溯演算法以...

演算法知識點整理 第6章 分支限界法

第 6 章 分支限界法 1.分支限界 vs 回溯 回溯 求出滿足問題的所有解,深度優先 分支限界 求出滿足問題的乙個解 或者是找出問題中的乙個最優解 廣度優先 都要先定 空間結構 兩者對當前擴充套件節點所採取的擴充套件方式不同。2.分支限界法常見方式 佇列式分支限界法 fifo 優先佇列式分支限界法...

演算法 分支限界法

在當前節點 擴充套件節點 處,先生成其所有的兒子節點 分支 然後再從當前的活節點 當前節點的子節點 表中選擇下乙個擴充套件節點。為了有效地選擇下乙個擴充套件節點,加速搜尋的程序,在每乙個活節點處,計算乙個函式值 限界 並根據函式值,從當前活節點表中選擇乙個最有利的節點作為擴充套件節點,使搜尋朝著解空...