分支限界算法

本文详细介绍了分支限界法的概念和工作原理,包括广度优先和优先队列式的分支限界策略。通过具体例子展示了如何利用分支限界法解决细胞查找和最少步数问题,并给出了相关代码实现。此外,还提到了分支限界法在单源最短路径、装载问题和0-1背包问题等领域的应用。
摘要由CSDN通过智能技术生成

分支限界算法策略
分支限界法常以广度优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。
分支节点的选择-常见的两种分支限界法
从活结点表中选择下一扩展结点的不同方式导致不同的分支限界法:
队列式(FIFO)分支限界法:按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。
优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。
最大优先队列:使用最大堆,体现最大效益优先
最小优先队列:使用最小堆,体现最小费用优先
【例】一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如:
阵列
4 10
0234500067
1034560500
2045600671
0000000089
有4个细胞。
#include
using namespace std;
int dx[4]={-1,0,1,0}, // x,y 方向上的增量
dy[4]={0,1,0,-1};
int bz[100][100],num=0,n,m; //二维数组,存储原始矩阵
void doit(int p,int q){ //p,q矩阵的行列号
int x,y,t,w,i;
int h[1000][2]; //顺序队列,记录入队细胞元素在二维数组中的位置
num++; //细胞个数增1
bz[p][q]=0; //细胞元素清0
t=0;w=1; //队列指针。t队首,w 队尾
h[1][1]=p; h[1][2]=q; //遇到的第一个细胞入队
do {
t++; //队头指针加1
for (i=0;i<=3;i++){ //沿细胞的上下左右四个方向搜索细胞
x=h[t][1]+dx[i];
y=h[t][2]+dy[i];
if ((x>=0)&&(x<m)&&(y>=0)&&(y<n)&&(bz[x][y])){
w++;
h[w][1]=x; h[w][2]=y; bz[x][y]=0;
} //本方向搜索到细胞就入队
}
}while (t<w); //直至队空为止
}
int main(){
int i,j;
char s[100],ch;
scanf("%d%d\n",&m,&n);
for (i=0; i<=m-1;i++ )
for (j=0;j<=n-1;j++ )
bz[i][j]=1; //初始化
for (i=0;i<=m-1;i++) {
gets(s);
for (j=0;j<=n-1;j++) if (s[j]==‘0’) bz[i][j]=0;
}
for (i=0;i<=m-1;i++)
for (j=0;j<=n-1;j++)
if (bz[i][j]) doit(i,j); //在矩阵中寻找细胞
printf(“NUMBER of cells=%d”,num);
return 0;
}

例二最少步数
在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(100*100)的围棋盘上任选两点A、B,A点放上黑子,B点放上白子,代表两匹马。棋子可以按“日”字走,也可以按“田”字走,俩人一个走黑马,一个走白马。谁用最少的步数走到左上角坐标为(1,1)的点时,谁获胜。现在他请你帮忙,给你A、B两点的坐标,想知道两个位置到(1,1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值