分支限界法和回溯法對比


from http://blog.csdn.net/wzwdcld/article/details/46125259 

方法

對解空間樹的搜索方式
存儲結點的常用數據結構
結點存儲特性
常用應用
回溯法
深度優先搜索
堆棧
活結點的所有可行子結點被遍歷后才被從棧中彈出
找出滿足約束條件的所有解
分支限界法
廣度優先或最小消耗優先搜索
隊列、優先隊列
每個結點只有一次成為活結點的機會
找出滿足約束條件的一個解或特定意義下的最優解
 
B、一個既可以采用回溯法也可以采用分支限界法解決的問題——0-1背包問題
0-1背包問題的解空間樹是一棵子集樹,所要求的解具有最優性質。
如果我們采用分支限界法解決這個問題,同樣需要用到貪心算法構造的上界函數,所不同的是,這個上界函數的作用不在於判斷是否進入一個結點的子樹繼續搜索,因為在搜索到達葉節點之前,我們也無法知道已經得到的最優解是什么。在這里,我們用一個最大堆來實現活結點的優先隊列,上界函數的值將作為優先級,這樣一旦有一個葉結點成為擴展結點,就表明已經找到了最優解。
C、一個比較適合采用分支限界法解決的問題——布線問題
布線問題的解空間是一個圖,適合采用隊列式分支限界法來解決。從起始位置a開始將它作為第一個擴展結點。與該結點相鄰並且可達的方格被加入到活結點隊列中,並且將這些方格標記為1,表示它們到a的距離為1。接着從活結點隊列中取出隊首作為下一個擴展結點,並將與當前擴展結點相鄰且未標記過的方格標記為2,並存入活節點隊列。這個過程一直繼續到算法搜索到目標方格b或活結點隊列為空時為止(表示沒有通路)。
現在來看上面兩張圖。左圖演示了分支限界法的過程。最開始,隊列中的活結點為標1的格子,隨后經過一個輪次,活結點變為標2的格子,以此類推,一旦b方格成為活節點便表示找到了最優方案。為什么這條路徑一定就是最短的呢?這是由於我們這個搜索過程的特點所決定的,假設存在一條由a至b的更短的路徑,b結點一定會更早地被加入到活結點隊列中並得到處理。 
還有許多類似於布線的問題可以為分支限界法提供良好的展示空間。在今年10月底剛剛結束的ACM競賽北京分賽區的比賽中,就出現一一個和布線問題十分相似的問題,可以用分支限界法取得很好的效果。
 
要做如何的處理才能解決這個問題呢?可以采取布線問題的解決框架,但是在每個結點處所出現的障礙物需要變化。如果我們僅僅在每個結點處把蛇身標記為與障礙物相同的記號固然是一種容易想到的思路,但是這樣處理不利於從一個格子的障礙物情形推廣到相鄰格子的障礙物情形。比較有效的做法是將蛇身描述成一個定長隊列,隊列首是蛇尾而隊列尾是蛇頭(如果為了思路的連貫性,也可以反過來處理,但是這樣應該使用雙向隊列),這樣一來從一個方格推廣到相鄰方格的時候,我們只要對這個隊列做一步處理就可以得到新的描述蛇身的隊列。然后,可以用這個隊列和方格本身的位置組成一個結構或類,在求解過程中依然使用隊列式分支限界法,只不過隊列中的元素是我們所定義的那個結構或類的對象。利用STL等一些泛型技術,這個過程還是比較容易實現的。

struct Position //描述一個位置的結構
{
int posx,posy; 
};

struct SnakeNode //描述分支限界法隊列中一個結點的結構
{
Position square ;//方格位置信息
list<Position> snakeBody(snakeLength);
//描述蛇身的隊列,每一個格的蛇仍用Position描述
}
這樣初始時我們用 queue<SnakeNode> nodeList(0)建立這個隊列,之后的過程和布線問題就基本一致了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM