算法设计与分析分支限界算法之细胞问题

mac2025-01-08  34

分支限界算法之细胞问题

问题描述

【例】一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如: 阵列 4 10 0234500067 1034560500 2045600671 0000000089 有4个细胞。

0234500067 按照上下左右的顺序进行检查,并将符合条件的依次入队 1034560500 解空间是一棵四叉树 2045600671 0000000089

为避免一个细胞被重复检查,需要将检测过的细胞数字清0

为避免一个细胞被重复检查,需要将检测过的细胞数字清0

0234500067 1034560500 2045600671 0000000089

算法分析

⑴从文件中读入m*n矩阵阵列,将其转换为boolean矩阵存入bz数组中; ⑵沿bz数组矩阵从上到下,从左到右,找到遇到的第一个细胞; ⑶将细胞的位置入队h,并沿其上、下、左、右四个方向上的细胞位置入队,入队后的位置bz数组置为false; ⑷将h队的队头出队,沿其上、下、左、右四个方向上的细胞位置入队,入队后的位置bz数组置为false; ⑸重复4,直至h队空为止,则此时找出了一个细胞; ⑹重复2,直至矩阵找不到细胞; ⑺输出找到的细胞数。

代码

【参考程序】 #include<cstdio> 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; }
最新回复(0)