目录
一、概述
- 回溯算法是深度优先,那么分支限界法就是广度优先的一个经典的例子。回溯法一般来说是遍历整个解空间,获取问题的所有解,而分支限界法则是获取一个解(一般来说要获取最优解)
- 分支限界算法课件的P19-P21
- 理解分支限界算法中也会利用约束函数和限界函数剪去无效的分支,提高搜索效率。
- 使用分支限界算法解决:计算细胞个数
- 知道单源最短路径问题、装载问题(最大装载量)、0-1背包问题、旅行商问题可以使用分支限界算法解决即可
二、计算细胞个数
矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右如果还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如阵列 :
4 10
0234500067
1034560500
2045600671
0000000089
有4个细胞。
分析:解空间是一棵四叉树
#include<iostream>
#include<bits/stdc++.h>
#include <queue>
using namespace std;
struct site{ int x,y;};
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 i; queue<site> qc;
num++; //细胞个数增1
struct site s,f;
s.x=p;s.y=q;
qc.push (s);
while(!qc.empty()){
f=qc.front ();
qc.pop ();
for (i=0;i<=3;i++){ //沿细胞的上下左右四个方向搜索细胞
s.x=f.x+dx[i]; s.y=f.y+dy[i];
if ((s.x>=0)&&(s.x<m)&&(s.y>=0)&&(s.y<n)&&(bz[s.x][s.y])){
qc.push(s);
bz[s.x][s.y]=0;
} //本方向搜索到细胞就入队
}
}
}
int main(){
int i,j;
char s[100];
cin>>m>>n; cin.get();
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]){
//bz[i][j]=0;
doit(i,j); //在矩阵中寻找细胞
}
cout<<"细胞个数="<<num<<endl;
return 0;
}