设图G的初始状态是所有顶点均未访问过。以G中任一顶点v为起点,则广度(宽度)优先搜索定义如下:
首先访问出发点v,接着依次访问v的所有邻接点w1,w2,……,wi,然后再依次访问与w1,w2,……,wi邻接
的所有未曾访问过的顶点。以此类推,直至图中所有和起点v有路径想通的顶点都已访问过。此时从v开始的搜索过程结束。
若G是连通图,则从任意顶点开始就能搜索完所有结点;否则,需要在图G中另选一个尚未访问的顶点作为新源点继续
上述的搜索过程,直至G中所有顶点均已被访问过。
网上看到过一个很形象的例子,这里借鉴一下用来加深理解。(出处:看雪。广度优先搜索)
比如:我们要从双子峰—->金门大桥,最短路径如何? 我们利用广度优先搜索来一步步求解,注意广度优先搜索在于的关键在于“广”,
也就是说以双子峰为起点,我们要尽可能的多比较与之相邻的周边路径,从其中选取一条最优路径。
第一步:
我们沿着两个箭头方向路径探索到a点和b点后,发现并没有到达想要去的地方,于是我继续往下探索。
同样,我们发现还没有到达目的地,继续往下探索。
到达这一步后,我们发现其中有一条路径已经到达金门大桥,而其他两条路径仅仅到达c点。因此,我们寻找到的最短路径为:
双子峰->a->c->金门大桥。
所以,由上我们可以知道,广度优先搜索其实就是用来探索最短路径的一种方式。
根据上面实例,我们想要寻找一条到某地的最短路径,需要一下两个步骤:
(1)使用图来建立问题模型。
(2)使用广度优先搜索解决问题。
利用广度优先搜索,我们可以回答两个问题:
1.从节点A出发,有前往B节点的路径吗?
2.从节点A出发,前往B节点哪条路径最短?
接下来看一下具体算法实现:
图一般可以用邻接表或邻近矩阵来表示,这里我们选用邻接矩阵。该算法主要用于解决在显示图中寻找某一方案的问题,如上述例子所述。
算法如下:
bfsm(int k,graph g[][100],int n){ //k是当前出发结点,g是邻接矩阵,n是所有 结点数量
int i,j;
queue Q;
InitQueue(Q); //队列初始化函数
//访问源点k
print("visit",k);
visited[k] = 1; //visited 数组记录结点被访问情况,初始化都置0
EnQueue(Q,k); //入队函数
while(!QueueEmpty(Q)) //QueueEmpty是判断队空函数
{
//i出队
i = DeQueue(Q); //出队函数
//扩展结点
for(j=0;j<n;j=j+1)
if(g[i][j]=1 and visited[j]=0)
{
print("visit vertex",j);
visited[j]=1;
EnQueue(Q,j);
}
}
}
接下来用Java实现从城市A到城市H的最短路径。
代码稍候贴上…