0.概念
分支限界法常以广度优先(队列式(先进先出)分支限界)或以最小耗费(最大效益)优先的方式(优先队列分支限界)搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。
1.与回溯法的不同
2.广度优先或以最小耗费优先的方式求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。
广度优先:与层次遍历相似,唯一的不同之处在于不再遍历不可行节点
最小耗费优先与贪心算法的不同:
从字面上的意思理解,最小耗费优先,是以最小耗费优先计算,并不是不将较大耗费的节点作为活节点了,只是在作为活节点的时候将较大耗费的那支给剪了;而贪心算法,是只计算最小耗费的节点,较大耗费的节点就不再作为活节点了。
A算法(启发式搜索)、贪心、分支限界求最优解的区别:
对当前优先搜索方向的判断标准为< 有可能的最优解 >。而最优解可以用一个评估函数来做,即已经有的耗散度加上以后有可能的耗度。A算法就是把两个耗散度加在一起,作为当前状态的搜索搜索方向;但是对以后的耗散度的评估是麻烦的,D(迪杰斯特拉,贪心)算法就是把当前有的路的最短的作为,以后耗散度的评估。分支限界算法就是只以以前的耗散度为评估函数。
3.单源最短路径
A.优先队列式分支界限
#include<iostream> #include<vector> #include<climits> #include<queue> using namespace std; vector< vector<int> > v; vector<int> dist; int num; struct Node { int i;//顶点i int len;//起点到顶点i的距离 }; struct cmp { bool operator ()(Node a,Node b) { return a.len>b.len; } }; void shortest(int start) { priority_queue<Node,vector<Node>,cmp> q; Node startv; startv.i=start; startv.len=0; q.push(startv); dist[start]=0; while(true) { for(int j=0;j<num;j++)//到哪个节点距离小,就将哪个节点作为扩展节点,并不是要按部就班的深度搜索,也不是以后不将耗费较大的做活节点了 { if(q.top().len+v[q.top().i][j]<dist[j]&&v[q.top().i][j]!=-1) { dist[j]=q.top().len+v[q.top().i][j]; Node temp; temp.i=j; temp.len=dist[j]; q.push(temp); } } if(q.empty()) { break; } else { q.pop(); } } } int main() { ci