【算法】BFS—广度优先搜索

原创 2018年04月15日 17:13:24

【算法】BFS—广度优先搜索

     1.BFS介绍

     2.连通图

     3.BFS算法流程图

     4.实例:poj3984迷宫问题

     5.核心代码


参考:

《算法导论》

【算法入门】广度/宽度优先搜索(BFS) https://blog.csdn.net/raphealguo/article/details/7523411

广度优先搜索算法 https://blog.csdn.net/ywjun0919/article/details/8838491

poj3984 迷宫问题 https://blog.csdn.net/u012679707/article/details/79952123

 

1.BFS介绍

宽度优先搜索算法(BFS,又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。

已知图G=(V,E)和一个源顶点s,宽度优先搜索以一种系统的方式探寻G的边,从而发现”s所能到达的所有顶点,并计算s到所有这些顶点的距离(最少边数),该算法同时能生成一棵根为s且包括所有可达顶点的宽度优先树。对从s可达的任意顶点v,宽度优先树中从sv的路径对应于图G中从sv的最短路径,即包含最小边数的路径。该算法对有向图无向图同样适用。

之所以称之为宽度优先算法,是因为算法自始至终一直通过已找到和末找到顶点之间的边界向外扩展,就是说,算法首先搜索和s距离为k的所有顶点,然后再去搜索和S距离为k+1的其他顶点。

BFS经典的例子就是走迷宫,我们从起点开始,找出到终点的最短路程,很多最短路径算法就是基于广度优先的思想成立的。

 

2.连通图

广度优先搜索是连通图的一种遍历策略,那就有必要将图先简单解释一下。


2-1 连通图示例图

如图2-1所示,这就是我们所说的连通图,这里展示的是一个无向图,连通即每2个点都有至少一条路径相连,例如V0到V4的路径就是V0->V1->V4。

一般我们把顶点用V缩写,把边用E缩写,图用G(V,E)表示。

 

3.BFS算法流程图

BFS假定输入图G=(V,E)采用邻接表表示,对于图中的每个顶点还采用了几种附加的数据结构,对每个顶点uV,其色彩存储于变量color[u]中,结点u的父母存于变量π[u]中。如果u没有父母(例如u=su还没有被检索到),则 π[u]=NIL,由算法算出的源点s和顶点u之间的距离存于变量d[u]中,算法中使用了一个先进先出队列Q来存放灰色节点集合。其中head[Q]表示队列Q的队头元素,Enqueue(Q,v)表示将元素v入队, Dequeue(Q)表示对头元素出队;Adj[u]表示图中和u相邻的节点集合。

伪代码如下:

procedure BFS(G,S);

  begin
1. for 每个节点u∈V[G]-{s} do
  begin
  2.color[u]←White;
  3. d[u]←∞;
  4. π[u]←NIL;
  end;

  5.color[s]←Gray;
  6. d[s]←0;
  7. π[s]←NIL;
  8. Q←{s}

  9. while Q≠φdo
  begin
  10.u←head[Q];
  11. for 每个节点v∈Adj[u] do
  12. if color[v]=White then
      begin
       13.color[v]←Gray;
       14.d[v]←d[v]+1;
       15. π[v]←u;
       16.Enqueue(Q,v);
      end;
  17.Dequeue(Q);
  18.color[u]←Black;
  end;
  end; 
                                       

                                                       BFS算法流程图

 

4.实例

实例搜索,要求V0V6的一条最短路。

                                                 

我们采用示例图来说明这个过程,在搜索的过程中,初始所有节点是白色(代表了所有点都还没开始搜索),把起点V0标志成灰色(表示即将辐射V0),下一步搜索的时候,我们把所有的灰色节点访问一次,然后将其变成黑色(表示已经被辐射过了),进而再将他们所能到达的节点标志成灰色(因为那些节点是下一步搜索的目标点了),但是这里有个判断,就像刚刚的例子,当访问到V1节点的时候,它的下一个节点应该是V0V4,但是V0已经在前面被染成黑色了,所以不会将它染灰色。这样持续下去,直到目标节点V6被染灰色,说明了下一步就到终点了,没必要再搜索(染色)其他节点了,此时可以结束搜索了,整个搜索就结束了。然后根据搜索过程,反过来把最短路径找出来,图3-1中把最终路径上的节点标志成绿色。                                             

                                

                                  

 实例应用:poj 3984 迷宫问题  https://blog.csdn.net/u012679707/article/details/79952123


5.核心代码
// BFS.c++

//广度优先搜索

 
 typedef struct
 {
      int x;
      int y;
 }Node;

 // Vs:startpoint
 // Vd:end point
 int Bfs(Node&Vs,Node& Vd)
 {
      queue<Node> Q;
      Node Vn,Vw; //Vn:当前节点; Vw:临近节点
      int i;
   
      //标记
        bool visit[MAX][MAX] ;   //颜色标记 ==true 说明该节点已被访问过
        Node mother[MAX][MAX];  //母亲节点
        int dis[MAX][MAX];     //距离
        
        //四个方向 (x,y)
        dir[][2]={     {0,1},{1,0},{0,-1},{-1,0}     } ;
        
        //初始状态将起点 加入队列
        Q.push(Vs);
        visit[Vs.x][Vs.y]=true;//设置该节点已被访问过
       //mother[Vs.x][Vs.y]=NIL;
       dis[Vs.x][Vs.y]=0;  //初始距离为0
        
        while( !Q.empty() )
        {
             //取出队列的头
             Vn=Q.front(); 
              Q.pop();
             
              for(i=0;i<4;i++)  //四个方向的 邻接点
              {
                     Vw=Node(Vn.x+dir[i][0],Vn.y+dir[i][1] ) ;//计算相邻节点
                     if(Vw==Vd)//找到终点了
                     {
                     //把路径记录下来,需根据情况添加代码
                     mother[Vs.x][Vs.y]=Vn;
                     dis[Vw.x][Vw.y]=dis[Vn.x][Vn.y]+1;
                     return true;
                     }
                    
                     if(isValid(Vw)&& !visit[Vw.x][Vw.y])  //Vw使一个合法的节点并且为白色
                     {
                         Q.push(Vw);//加入队列                         
                         visit[Vw.x][Vw.y]=true;//设置节点颜色
                         mother[Vs.x][Vs.y]=Vn;//父辈节点
                         dis[Vw.x][Vw.y]=dis[Vn.x][Vn.y]+1;                    
                     }
              }
        }
 return false;  //无解,此无通路   
}
-------------------------------------------         END      -------------------------------------

左转算法C++实战

仓促的放在网上,如有错误,欢迎指正。具体代码可发邮件jihailongs@163.com
  • qq_21091051
  • qq_21091051
  • 2016-12-26 19:23:06
  • 573

人工智能之搜索策略-A*算法入门

中文原文:http://blog.csdn.net/pojianbing/article/details/5649142 英文原文:http://www.gamedev.net/page/resou...
  • dahuacai
  • dahuacai
  • 2016-01-11 17:23:53
  • 3716

A* 寻路算法

A* 寻路算法 原文地址: http://www.gamedev.net/reference/articles/article2003.asp 概述 虽然掌握了 A* 算法的人认为它容易,但是对于初...
  • zyh821351004
  • zyh821351004
  • 2015-08-14 20:36:57
  • 1193

【算法】广度优先搜索(BFS)I

1. 算法描述 2. Referrence 3. 问题 3.1 POJ 3278 追及问题,在n处的FJ可以左移、右移,也可以成两倍地移,求最快需要多少步追上在k处的cow。 可以...
  • lifehack
  • lifehack
  • 2013-12-01 20:44:05
  • 5091

[数据结构]广度优先搜索算法(Breadth-First-Search,BFS)

广度优先搜索的概念 广度优先搜索(BFS)类似于二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,然后由v出发,依次访问v的各个未被访问过的邻接顶点w1,w2,w3….wn,然后再依次访问w1...
  • m0_37316917
  • m0_37316917
  • 2017-04-27 21:26:22
  • 3808

A*寻径算法新手入门

译者说:无论是现在风靡的网页游戏,还是老牌的网络游戏,寻径几乎都是难以回避的一个话题,而寻径必然从A*算法开始。关于A*国外相关的资料相当丰富,很多时候让我们为难的还不是具体的算法,而是A*的基本思路...
  • pojianbing
  • pojianbing
  • 2010-06-05 11:31:00
  • 2708

搜索网站

想要搜索首相要了解一下有哪些知名的搜索网站。 国外最受欢迎的10个搜索引擎网站   1、谷歌 Google    谷歌(Google)是美国一家专门从事互联网相关服务和产品的跨国公司。...
  • DYC410181341
  • DYC410181341
  • 2014-10-07 15:28:43
  • 4795

[C++]广度优先搜索(BFS)(附例题)

广度优先搜索(BFS)(附例题)问题产生:Isenbaev是国外的一个大牛。现在有许多人要参加ACM ICPC。一共有n个组,每组3个人。同组的3个人都是队友。大家都想知道自己与大牛的最小距离是多少。...
  • stary_yan
  • stary_yan
  • 2016-05-08 14:16:51
  • 8001

训练第二周之BFS算法(广度优先搜索)

本篇参考自rapheal的【算法入门】广度/宽度优先搜索(BFS),觉得写得超级赞,大家去他那里相信会有很多收获。基本简介:每次将集合中的元素经过一些改动,分层生成当前状态的子状态(通常还删除父情况)...
  • a747979985
  • a747979985
  • 2016-07-21 19:03:15
  • 797

粒子群优化算法介绍

http://pbking1.github.io/blog/2014/04/07/something-about-pso-algorithm/ KING Do more, say le...
  • kebu12345678
  • kebu12345678
  • 2017-03-04 09:59:28
  • 7127
收藏助手
不良信息举报
您举报文章:【算法】BFS—广度优先搜索
举报原因:
原因补充:

(最多只允许输入30个字)