1. 介绍

本文介绍了比较初级的图搜索算法,包括深度优先遍历,广度优先遍历和双向广度优先遍历。

2. 深度优先遍历DFS

2.1 算法思想

从图中某个顶点v开始,访问此节点,然后依次从v中未被访问的邻接点出发深度优先遍历图,直到图中上所有和v有路径相通的顶点都被访问;若此时图中尚有顶点未被访问,则另选图中一个未被访问顶点做起点,重复以上过程,直到图中所有顶点都被访问为止。

深度优先搜索遍历类似于树的先序遍历。假定给定图G的初态是所有顶点均未被访问过,在G中任选一个顶点i作为遍历的初始点,则深度优先搜索遍历可定义如下:

(1) 首先访问顶点i,并将其访问标记置为访问过,即visited[i]=1;

(2) 然后搜索与顶点i有边相连的下一个顶点j,若j未被访问过,则访问它,并将j的访问标记置为访问过,visited[j]=1,然后从j开始重复此过程,若j已访问,再看与i有边相连的其它顶点;

(3) 若与i有边相连的顶点都被访问过,则退回到前一个访问顶点并重复刚才过程,直到图中所有顶点都被访问完止。

2.2 算法实现

邻接矩阵的算法描述为下面形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void dfs1 (graph & g, int i, int n)         // 从顶点i 出发遍历
{
  cout<<g.v[i];                //输出访问顶点
  visited[i]=1;                    //访问标记置1表示已经访问
  for(j=1; j<=n; j++)
    if ((g.arcs[i ][j]= =1)&&(!visited[j]))
      dfs(g,j,n);
}

邻接表算法描述为下面形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void  dfs2(adjlist GL,int i, int n)
{
  cout<<i<<‘’ ;              //输出访问顶点
  visted[i]=1;            //访问标记置为1表示已访问
  edgenode * p=GL[i];
  while (p!=NULL)
  {
     if  (!visited[p->adjvex])
       dfs2(p->adjvex);
     p=p->next;
  }
 }

2.3 适用范围

需要有顺序遍历图,且找到一个解后输出即可。如:trie树排序

多用于只要求解,并且解答树中的重复节点较多并且重复较难判断时使用,但往往可以用A*或回溯算法代替。

2.4 举例

数独求解。给出一个不完整的数独,让填充其中空白的数字。

更多题目:

POJ 1321 棋盘问题:http://www.cublog.cn/u3/105033/showart_2212140.html

类迷宫问题:http://www.jguoer.com/post/2010/02/17/DFS-Code.aspx

数独问题:http://acm.hdu.edu.cn/showproblem.php?pid=1426

3. 广度优先遍历BFS

3.1 算法思想

广度优先搜索遍历类似于树的按层次遍历。设图G的初态是所有顶点均未访问,在G 任选一顶点i作为初始点,则广度优先搜索的基本思想是:

(1)首先访问顶点i,并将其访问标志置为已被访问,即visited[i]=1;

(2)接着依次访问与顶点i有边相连的所有顶点W1,W2,…,Wt;

(3)然后再按顺序访问与W1,W2,…,Wt有边相连又未曾访问过的顶点;

依此类推,直到图中所有顶点都被访问完为止。

3.2 算法实现

用邻接矩阵的算法描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void  bfs1( graph g, int  i)       //从顶点i出发遍历
{
  Queue  Q ;         //Q为队列
  InitQueue(Q)
  cout<<g.v[i] ;        // 输出访问顶点
  visited[i]=1 ;         //标记置1表示已经访问
  Qinsert(Q,i) ;          //入队列
  while (!Queueempty(Q))
  {
    int k=Qdelete(Q);
    for (j=0; j<n; j++)
    {
      if ((g.a[i][j]==1)&&(!visited[j]))
      {
        cout<<g.v[j];
        visited[j]=1 ;
        Qinsert(Q,i) ;
      }
    }
  }
}

用邻接矩阵的算法描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void  bfs2(adjlist GL, int i, int n)
{
  Queue Q ;
  InitQueue(Q);               //定义队列
  cout<<i<<‘’;
  visited[i]=1;
  Qinsert(Q,i)                                //进队
  while (!QueueEmpty(Q))
  {
    int k=Qdelete(Q) ;            //出队
    edgenode* p=GL[k];
    while  (p!=NULL)
    {
      if (!visited[p->adjvex])
      {
        cout<<j;
        visited[p->data]=1;
        Qinsert(Q);
      }
    p=p->next;
    }
  }
}

3.3 适用范围

求问题的最优解

3.4 举例

给定一个8*8的格子地图,再给定初始状态和终止状态,输出从初始点到达终止点的最少步数。

更多题目:

http://www.cppblog.com/firstnode/archive/2009/03/07/75839.html

http://blog.sina.com.cn/s/blog_6635898a0100hwe3.html

http://blog.csdn.net/super_chris/archive/2009/12/26/5082666.aspx

http://www.chenyajun.com/2010/05/08/4540

4. 双向广度优先遍历

4.1 算法思想

有些问题按照广度优先搜索法则扩展结点的规则,既适合顺序,也适合逆序,于是我们考虑在寻找目标结点或路径的搜索过程中,初始结点向目标结点和目标结点向初始结点同时进行扩展,直至在两个扩展方向上出现同一个子结点,搜索结束,这就是双向搜索过程。

出现的这个同一子结点,我们称为相交点,如果确实存在一条从初始结点到目标结点的最佳路径,那么按双向搜索进行搜索必然会在某层出现“相交”,即有相交点,初始结点一相交点一目标结点所形成的一条路径即是所求路径。

4.2 算法实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
now = 0;
Q.push(st);    RQ.push(ed);
mark[st] = true;    Rmark[ed] = true;
while(!Q.empty() && !RQ.empty())
{ // 两边的扩展方式须为按层扩展
  while(Q.front().step == now)
  { //step表示节点的层数
    nextState = extend(Q.front); t
    if(mark[nextState]) continuel
    if(Rmark[nextState]) return true;
  }
  while(RQ.front().step == now)
  {
    nextState = extend(RQ.front);
    if(Rmark[nextState]) continuel
    if(mark[nextState]) return true;
  }
  now++;
}

4.3 适用范围

最优化问题中,知道问题的起始状态和最终状态,且两个状态可相互到达。

4.4 举例

棋盘上有四个棋子,给你两个状态,问可否8步内将一个状态转移到另一个状态?

5. DFS与BFS比较

数据结构:DFS采用栈,而BFS采用队列

算法思想:深度搜索与广度搜索的控制结构和产生系统很相似,唯一的区别在于对扩展节点选取上。由于其保留了所有的前继节点,所以在产生后继节点时可以去掉一部分重复的节点,从而提高了搜索效率。这两种算法每次都扩展一个节点的所有子节点,而不同的是,深度搜索下一次扩展的是本次扩展出来的子节点中的一个,而广度搜索扩展的则是本次扩展的节点的兄弟节点

使用范围:DFS可以迅速的找到一个解,然后利用这个解进行剪枝,而BFS可找到最优解。

原创文章,转载请注明: 转载自董的博客

本文链接地址: http://dongxicheng.org/structure/basic-graph-search/

算法之图搜索算法(一)相关推荐

  1. 地图绘制和四色算法,图搜索算法,最小生成树算法,最短路径算法

    基于简易Web墨卡托计算实现地图绘制,四色染色,实现图的深度优先搜索,广度优先搜索,Kruskal算法最小生成树,Prime算法最小生成树,Dijkstra最短路径算法. 使用Java & S ...

  2. 全局路径规划:图搜索算法介绍2(A star)

    接下来要介绍的是基于贪心算法的图搜索算法Dja, 和 A* 什么是贪心算法?意思就是我们总是向离终点最近的搜索方向去搜索: Dja 算法的原理就是通过对搜索点构造cost function, 搜索方向 ...

  3. Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS、深度优先DFS,最短路径SPF、带负权的最短路径Bellman-ford、拓扑排序)

    Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS.深度优先DFS,最短路径SPF.带负权的最短路径Bellman-ford.拓扑排序) 目录 一.图的搜索 1.BFS (Brea ...

  4. 全局路径规划:图搜索算法介绍6(A star)Matlab算法实现

    本文接:全局路径规划:图搜索算法介绍2(A star) https://blog.csdn.net/gophae/article/details/103061702 % This is Yunchen ...

  5. 全局路径规划:图搜索算法介绍1(BFS/DFS)

    对于全局路径规划的设计,我们先要了解什么是图搜索,在此之前,要先知道什么是图: 可以看到,图有很多种,有无向图,有向图,节点之间还可以有不同的weight, 用于表述从节点与节点直接迁移的代价. 而图 ...

  6. 图搜索算法(一):图搜索的一般算法

    一.引言 图搜索技术时人工智能中的核心技术之一,并且在其他场合也有着非常广泛的应用.这里的图称为状态图,指由节点和有向(带权)边所做成的网络,每个节点即状态.按照搜索的方式不同,图搜索一般分为树式搜索 ...

  7. 图搜索算法UCS(一致代价搜索)通俗易懂图示详解

    一致代价搜索实际上是在BFS(广度优先搜索算法)的基础上进行扩展的,我们在上一篇博客图搜索算法BFS和DFS通俗易懂图示详解中提到,BFS是基于队列数据结构的,既然UCS是BFS的扩展,那么UCS一定 ...

  8. 路径规划算法1.1图搜索算法——可视图法

    路径规划算法1.1图搜索--可视图法 前言 图搜索算法 可视图法 前言 机器人自主运动三巨头:感知,规划,控制.规划又包括运动规划.路径规划.路径规划又包括全局规划,局部规划. 路径规划,就是在给定的 ...

  9. python画心形代码大全_Python代码合集看点 机器人算法、自动导航算法算法大全...

    导读:本文包含机器人算法.自动导航算法的Python代码合集.其主要特点有以下三点:选择了在实践中广泛应用的算法:依赖最少.容易阅读,容易理解每个算法的基本思想.希望阅读本文后能对你有所帮助.文章来源 ...

最新文章

  1. 【Data Algorithms CHP07】数组生成组合排列
  2. 梯度下降法(一)入门
  3. 2020 我的C++的学习之路
  4. 队列表mysql,什么是在mysql中实现消息队列表的最佳方法
  5. java类后面的尖括号_泛型 - Java中的T(尖括号)是什么意思?
  6. android studio 创建项目失败原因Failed to create
  7. vue省市区三级联动(行政区划代码)
  8. 汇编版|电子印章在各类业务文件中的应用
  9. 宇视网络视频录像机添加第三方摄像机的配置方法
  10. 简单说明什么是网络的DMZ区域
  11. 生信过程中的各种文件格式
  12. 2018 AI产业界大盘点
  13. matlab开普勒方程求地球偏心距,第二章-开普勒方程PPT课件
  14. 微信开发工具更新后,跳转页面报错
  15. 强烈推荐提升自我的30个好习惯
  16. 职场人士必学的10种Excel打印技巧【特别实用,赶紧收藏】
  17. LocalDateTime获取服务器当前时间----24小时与12小时
  18. USACO 2.1.4 健康的荷斯坦奶牛 Healthy Holsteins
  19. SD-Host SD_CLK模块
  20. 移动通讯中的2G和2.5G以及3G概念

热门文章

  1. 王者荣耀全栈项目部署到阿里云服务器笔记
  2. 蚂蚁金服成立科学智囊团,机器学习之父Michael I.Jordan担任主席
  3. 快的打车联合创始人兼技术副总裁闻诚:CTO要有“334”能力
  4. 项目实战-本地自动化部署
  5. 河南测绘职业学院招生计算机,河南测绘职业学院代码
  6. 无名飞控c语言源码,stm32飞控
  7. android小部件如何实时更新,android – 使用AlarmManager手动更新小部件
  8. Matlab-基于短时神经网络的声音分类
  9. 卡尔曼滤波器原理和matlab实现
  10. java call back_java中Callback简单使用总结