分支限界法类似与回溯法,也是一种在问题的解空间树上搜索问题的解法。但后者的目标是找到满足约束条件的所有解,而前者要求找到某种意义下的最优解(极大值、极小值)。
分支限界法采用广度优先的策略,依次搜索活结点的所有分支,也就是所有相邻结点。
定义一个二维数组,例如:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
输入格式:
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一最短路径。
输出格式:
左上角到右下角的最短路径,格式如样例所示。
输入样例:
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
getAns(queue *q,dot d[],int pos){
int i=0;
if(pos==24)//已到达终点(4,4)
if(d[pos].countminnum)
return;//若已大于最小点数但还未到终点,剪枝
if(pos%5!=4&&d[pos+1].num!=1){//不在右边界
Push(q,d[pos+1]);
d[pos+1].count=d[pos].count+1;
for(i=0;i<25;i++)
d[pos+1].temp[i]=d[pos].temp[i];
d[pos+1].temp[d[pos+1].count]=pos+1;
getAns(q,d,pos+1);
}
if(pos/5!=4&&d[pos+5].num!=1){//不在下边界
Push(q,d[pos+5]);
d[pos+5].count=d[pos].count+1;
for(i=0;i<25;i++)
d[pos+5].temp[i]=d[pos].temp[i];
d[pos+5].temp[d[pos+5].count]=pos+5;
getAns(q,d,pos+5);
}
if(pos/5!=0&&d[pos-5].num!=1){//不在上边界
Push(q,d[pos-5]);
d[pos-5].count=d[pos].count+1;
for(i=0;i<25;i++)
d[pos-5].temp[i]=d[pos].temp[i];
d[pos-5].temp[d[pos-5].count]=pos-5;
getAns(q,d,pos-5);
}
if(pos%5!=0&&d[pos-1].num!=1){//不在左边界
Push(q,d[pos-1]);
d[pos-1].count=d[pos].count+1;
for(i=0;i<25;i++)
d[pos-1].temp[i]=d[pos].temp[i];
d[pos-1].temp[d[pos-1].count]=pos-1;
getAns(q,d,pos-1);
}
}
分支限界法按广度优先策略搜索问题的解空间树,在搜索过程中,对待处理的结点根据限界函数估算目标函数的可能取值,从中选取使目标函数取得极值(极大或极小)的节点优先进行广度搜索,从而不断调整搜索方向,尽快找到问题的解。
由于限界函数一般基于问题的目标函数决定,因此,分支限界法适用于求解最优解问题或者较小代价找出满足条件的答案解。