分支定界演算法
1、概念:
分支定界演算法(Branch and bound,簡稱為 BB、B&B, or BnB)始終圍繞著一顆搜尋樹進行的,我們將原問題看作搜尋樹的根節點,從這裡出發,分支的含義就是將大的問題分割成小的問題。大問題可以看成是搜尋樹的父節點,那麼從大問題分割出來的小問題就是父節點的子節點了。分支的過程就是不斷給樹增加子節點的過程。而定界就是在分支的過程中檢查子問題的上下界,如果子問題不能產生一比當前最優解還要優的解,那麼砍掉這一支。直到所有子問題都不能產生一個更優的解時,演算法結束。
2、例子:
用BB演算法求解下面的整數規劃模型
因為求解的是最大化問題,我們不妨設當前的最優解BestV為-INF,表示負無窮。
-
首先從主問題分出兩支子問題:
通過線性鬆弛求得兩個子問題的upper bound為Z_LP1 = 12.75,Z_LP2 = 12.2。由於Z_LP1 和Z_LP2都大於BestV=-INF,說明這兩支有搞頭,繼續往下。 -
從節點1和節點2兩個子問題再次分支,得到如下結果:
子問題3已經不可行,無需再理。子問題4通過線性鬆弛得到最優解為10,剛好也符合原問題0的所有約束,在該支找到一個可行解,更新BestV = 10。
子問題5通過線性鬆弛得到upper bound為11.87>當前的BestV = 10,因此子問題5還有戲,待下一次分支。而子問題6得到upper bound為9<當前的BestV = 10,那麼從該支下去找到的解也不會變得更好,所以剪掉! -
對節點5進行分支,得到:
子問題7不可行,無需再理。子問題8得到一個滿足原問題0所有約束的解,但是目標值為4<當前的BestV=10,所以不更新BestV,同時該支下去也不能得到更好的解了。 -
此時,所有的分支遍歷都完成,我們最終找到了最優解。
3、演算法過程(以最小化問題minimize f(x)為例)
1、使用啟發式,找到優化問題的解決方案xh。 儲存其值,B = f(x_h)。 (如果沒有啟發式可用,則將B設定為無窮大。)B將表示到目前為止找到的最佳解,並將用作候選解的上界。
2、初始化佇列以儲存部分解決方案,但不分配任何問題變數。
3、迴圈直到佇列為空:
3.1從佇列中取出一個節點N.
3.2如果N代表單個候選解x和f(x)<B,則x是迄今為止的最佳解。 記錄並設 置B←f(x)。
3.3否則,在N上分支以產生新的節點Ni。 對於每個新節點:
3.3.1如果下線(N_i)> B,則什麼都不做; 由於此節點的下限大於問題的上限,因此它永遠不會導致最優解,並且可以被丟棄。
3.3.2否則,將Ni存入佇列。
其實程式碼該過程描述也很明瞭了。第1步可以用啟發式找一個當前最優解B出來,如果不想也可以將B設定為正無窮。對於一個最小化問題而言,肯定是子問題的lower bound不能超過當前最優解,不然超過了,該子問題就需要剪掉了。
第2第3步主要是用佇列取構建一個搜尋樹進行搜尋,具體的搜尋方式由queue這個資料結構決定的。
注:B&B是圍繞著一顆搜尋樹進行的,那麼對於一棵樹而言就有很多種搜尋方式
1)Breadth-first search (BFS):廣度優先搜尋,就是橫向搜尋,先搜尋同層的節點。再一層一層往下。這種搜尋可以用FIFO queue實現。
2)Depth-first search (DFS):深度優先搜尋,就是縱向搜尋,先一個分支走到底,再跳到另一個分支走到底。這種搜尋可以用LIFO queue也就是棧實現。
3)Best-First Search:最佳優先搜尋,最佳優先搜尋演算法是一種啟發式搜尋演算法(Heuristic Algorithm),其基於廣度優先搜尋演算法,不同點是其依賴於估價函式對將要遍歷的節點進行估價,選擇代價小的節點進行遍歷,直到找到目標點為止。這種搜尋可以用優先佇列priority queue來實現。
注:本文轉載自
https://mp.weixin.qq.com/s?__biz=MzI3NTkyODIzNg==&mid=2247484832&idx=1&sn=d420a9a535348b0469606419a7c07aeb&chksm=eb7c0063dc0b8975d64931b5b35e971f6cf78972fbdc7705bb2f16ebba39a2402f2025eff8c9&mpshare=1&scene=1&srcid=&sharer_sharetime=1567610382445&sharer_shareid=054592193644de509623829748e83807&key=5c697a296e1d5a5c0aba9025fae36affa28405e30ce73943ae79c9507ddef6272747ec2f7f4109c201f2611d1e2f31645c71b84a0e797baf3f823a74aa6a2be0758d93c87f32996af02f012ee77ae1a2&ascene=1&uin=MjYzMDA1MzAyMQ%3D%3D&devicetype=Windows+10&version=62060834&lang=zh_CN&pass_ticket=x2YOENqmw1WX%2BbY2oMQM2%2FvgZw9bCyJdvL36g%2Fad0MnNoTVOTcP2gVVONuueS7VV
相關文章
- 【演算法】分支界限法演算法
- Git(12)-- Git 分支 - 分支簡介Git
- 同步master主分支,覆蓋xxx分支AST
- Git 分支 - 分支的新建與合併Git
- git分支Git
- gitlab一個分支落後於主分支,怎麼同步主分支的提交Gitlab
- 小編帶你學定界符之nowdoc和heredoc有區別嗎?
- 城中分支
- git分支操作Git
- 分支結構
- Git 分支管理Git
- Git 分支操作Git
- Git 使用分支Git
- 新建recommend分支
- Git 操作——如何刪除本地分支和遠端分支Git
- Git 分支策略與submodule對分支策略的影響Git
- Git dev分支合併到master分支完美實戰GitdevAST
- gitlab分支保護Gitlab
- Gitlab刪除分支Gitlab
- 前端分支規範前端
- Git——分支管理(2)Git
- git合併分支Git
- Vue 分支迴圈Vue
- Gitflow分支管理策略Git
- python分支語句Python
- 新建分支 header區Header
- Git分支的作用Git
- Git新建branch分支Git
- Git分支切換Git
- git-分支管理Git
- git刪除本地分支命令 git怎麼刪除本地分支Git
- git本地分支對映遠端分支並推送相應程式碼Git
- SVN使用教程:將online分支的程式碼合併到sprint分支
- FSAF:嵌入anchor-free分支來指導acnhor-based演算法訓練 | CVPR2019演算法
- 開發分支管理策略
- Git 與遠端分支Git
- 運算子、分支語句
- 常見的Linux分支Linux