算法设计与 第五章1图的搜索算法_第1页
算法设计与 第五章1图的搜索算法_第2页
算法设计与 第五章1图的搜索算法_第3页
算法设计与 第五章1图的搜索算法_第4页
算法设计与 第五章1图的搜索算法_第5页
已阅读5页,还剩149页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第五章 图的搜索算法 5 51 1 图搜索概述图搜索概述 5.1.15.1.1 图及其术语图及其术语 5.1.25.1.2 图搜索及其术语图搜索及其术语5 52 2 广度优先搜索广度优先搜索 5.2.15.2.1 算法算法框架框架 5.2.25.2.2 广度优先搜索广度优先搜索的的应用应用5.3 5.3 深度优先搜索深度优先搜索 图是一种限止最少的数据结构,因此更接近现实,实际图是一种限止最少的数据结构,因此更接近现实,实际问题中很多数据关系都可以抽象成图,相关问题则可利用图问题中很多数据关系都可以抽象成图,相关问题则可利用图的基本算法进行求解,很早就有专门研究图的是一门数学学的基本算法进行求

2、解,很早就有专门研究图的是一门数学学科科“图论图论”;其中的计算问题包括;其中的计算问题包括图的搜索、路径问题、连图的搜索、路径问题、连通性问题、可平面性检验、着色问题、网络优化通性问题、可平面性检验、着色问题、网络优化等。图论中等。图论中的著名算法有:求最小生成树的的著名算法有:求最小生成树的Kruskal算法、求最短路径算法、求最短路径的的Dijkstra算法和算法和Floyd算法、求二部图最大匹配(指派问算法、求二部图最大匹配(指派问题)的匈牙利算法、求一般图最大匹配的题)的匈牙利算法、求一般图最大匹配的Edmonds“花花”算法、算法、求网络最大流和最小割求网络最大流和最小割的算法等。

3、其中的一些算法在数据结的算法等。其中的一些算法在数据结构课程中已经学习过了。构课程中已经学习过了。 1显式图与隐式图显式图与隐式图 在路径问题、连通性问题、可平面性检验、着色在路径问题、连通性问题、可平面性检验、着色问题和网络优化等问题中,图的结构是显式给出的,问题和网络优化等问题中,图的结构是显式给出的,包括图中的顶点、边及权重,这类图我们称为包括图中的顶点、边及权重,这类图我们称为显式图显式图,也就是一般意义上的图。也就是一般意义上的图。 隐式图隐式图是由问题的初始结点,为了求解或求证是由问题的初始结点,为了求解或求证问题,根据题目的规则(一般是由题目的意思隐含问题,根据题目的规则(一般是

4、由题目的意思隐含给出的),也就是生成子结点的约束条件,逐步扩给出的),也就是生成子结点的约束条件,逐步扩展结点,直到得到目标结点为止的一个展结点,直到得到目标结点为止的一个隐式的图隐式的图。 5 51 11 1 图及其术语图及其术语2.2.显式图的常用术语显式图的常用术语 如图如图5-1所示的所示的 , , 均为显式图均为显式图 (Graph)。图。图中的这些点中的这些点(v1,v2,vn)(v1,v2,vn)被称为被称为顶点顶点 (vertex)或结点或结点,连,连接顶点的曲线或直线称为接顶点的曲线或直线称为边边 (edge)。 通常将这种由若干个顶点以及连接某些顶点的边所组通常将这种由若干

5、个顶点以及连接某些顶点的边所组成的图形称为图,顶点通常被称作是图中的数据元素成的图形称为图,顶点通常被称作是图中的数据元素 .v1v2v3v4v1v3v2v4v1v2v3v4v5图图 5-1 v1v3v2v434296图图 5-2 带权图带权图:j即图即图5 -2给图给图 5-1中各图的边上附加一个代表性数据中各图的边上附加一个代表性数据 (比比如表示长度、流量或其他如表示长度、流量或其他 ),则称其为带权图,则称其为带权图 。环环 (cycle):图:图5-1中中 图中的图中的 v 1点本身也有边相连,这种边称点本身也有边相连,这种边称为环。为环。 有限图有限图:顶点与边数均为有限的图,如图

6、:顶点与边数均为有限的图,如图 5-1中的三个图均属于中的三个图均属于有限图。有限图。 简单图简单图:没有环且每两个顶点间最多只有一条边相连的图,如图:没有环且每两个顶点间最多只有一条边相连的图,如图 5-1中的中的 图。图。 邻接与关联邻接与关联:当(:当( v 1, v 2) E,或,或 E,即,即 v 1, v 2间有边相连时,则称间有边相连时,则称 v 1和和 v 2是相邻的,它们互为邻接点是相邻的,它们互为邻接点( adjacent),同时称(),同时称( v 1, v 2)或)或 是与顶点是与顶点 v 1、 v 2相关联的边。相关联的边。 顶点的度数顶点的度数 (degree):从

7、该顶点引出的边的条数,即与该:从该顶点引出的边的条数,即与该顶点相关联的边的数目,简称度。顶点相关联的边的数目,简称度。入度入度( indegree):有向图中把以顶点):有向图中把以顶点 v为终点的边的条为终点的边的条数称为是顶点数称为是顶点 v的入度。的入度。 出度出度( outdegree):有向图中把以顶点):有向图中把以顶点 v为起点的边的条为起点的边的条数称为是顶点数称为是顶点 v的出度。的出度。终端顶点:有向图中把出度为终端顶点:有向图中把出度为 0的顶点称为终端顶点,如图的顶点称为终端顶点,如图 5-1中中 图的图的 v 3。 路径与路长路径与路长:在图:在图 G=( V, E

8、)中,如果存在由不同的边中,如果存在由不同的边 (v i0, v i1 ), (v i1, v i2 ), , (v in-1, v in )或是或是 , , , )组成组成的序列,则称顶点的序列,则称顶点 v i0, v in是连通的,顶点序列(是连通的,顶点序列( v i0, v i1, v i2, , v in)是从顶点)是从顶点 v i0到顶点到顶点 v in的一条的一条道路。路长是道路上边的数目,道路。路长是道路上边的数目, v i0到到 v in的这条道路上的这条道路上的路长为的路长为 n。 连通图连通图:对于图中任意两个顶点:对于图中任意两个顶点 v i、 v j V, v i、

9、 v j之之间有道路相连,则称该图为连通图。如间有道路相连,则称该图为连通图。如 5-1中的中的 图。图。网络网络:带权的连通图,如图:带权的连通图,如图 5-2所示。所示。3隐式图术语 1)子集树 当要求解的问题需要是在当要求解的问题需要是在n n 个元素的子集中进行搜索,其搜个元素的子集中进行搜索,其搜索空间树被称作索空间树被称作子集树子集树(subset treesubset tree)。这)。这n n个元素都有在子个元素都有在子集中或被选取记为集中或被选取记为1 1,不在子集中或被舍去记为,不在子集中或被舍去记为0 0,这样搜索空,这样搜索空间为:间为: (0 0,0 0,0 0,0

10、0),(),(0 0,0 0,0 0,1 1),), (0 0,0 0,1 1,0 0),(),(0 0,0 0,1 1,1 1),), (1 1,1 1,1 1,1 1)。)。共共2 2n n 个状态。若表示为树形结构就是一棵有个状态。若表示为树形结构就是一棵有2 2n n个叶结点的二叉个叶结点的二叉树,对树中所有分支进行遍历的算法都必须耗时树,对树中所有分支进行遍历的算法都必须耗时O(2n)。)。 图图5-3 n=3的子集树的子集树 当要求解的问题需要在当要求解的问题需要在n n 元素的排列中搜索问题的解时,元素的排列中搜索问题的解时,解空间树被称作解空间树被称作排列树排列树(permut

11、ation treepermutation tree)。)。搜索空间为:搜索空间为:(1 1,2 2,3 3,n-1n-1,n n), , (2 2,1 1,3 3,n-1n-1,n n), , (2 2,3 3,1 1,n-1n-1,n n), ,(2 2,3 3,4 4,1 1,n-1n-1,n n), ,(n n,n-1n-1,3 3,2 2,1 1) 第一个元素有第一个元素有n 种选择,第二个元素有种选择,第二个元素有n-1种选择,第三个种选择,第三个元素有元素有n-2种选择,种选择,第,第n个元素有个元素有1种选择,共计种选择,共计n!个状态。个状态。若表示为树形就是一个若表示为树形

12、就是一个n度树,这样的树有度树,这样的树有n! 个叶结点,所以每个叶结点,所以每一个遍历树中所有节点的算法都必须耗时一个遍历树中所有节点的算法都必须耗时O(n! ) 2)排列树 图图5-3 n=4的部分子集树的部分子集树 12503418 X1=115121o75173133282623211383292419454035615651141196416303227252220234 X2=2341 3 41 241 23X3=311 43 42 32 43 44 3 4 2 3 2 4 3 4 1 3 x4=1 4图的存储 1)邻接矩阵法 邻接矩阵是表示顶点之间相邻关系的矩阵,邻接矩阵是表示顶

13、点之间相邻关系的矩阵,设设G=(V,E)G=(V,E)是具有是具有n n个顶点的图,则个顶点的图,则G G的邻接矩阵可定义为:的邻接矩阵可定义为: Ai,j=1, Ai,j=1, 若(若(Vi,Vj)Vi,Vj)或或是是E(G)E(G)中的边。中的边。 Ai,j=0, Ai,j=0, 若若 (Vi,Vj)(Vi,Vj)或或不是不是E(G)E(G)中的边。中的边。若若G G是网络,则邻接矩阵可定义为:是网络,则邻接矩阵可定义为: Ai,j=WAi,j=Wij ij 若(若(Vi,Vj)Vi,Vj)或或属于属于E(G);E(G); Ai,j=0或或 若(若(Vi,Vj)或)或 不属于不属于E(G)

14、; 其中,其中,Wij表示边上的权值,表示边上的权值,表示一个计算机允许的,大于表示一个计算机允许的,大于所有边上权值的数;所有边上权值的数; 2)邻接表 对于图对于图G G中的每个结点中的每个结点Vi, Vi, 把所有邻接于把所有邻接于ViVi的顶点的顶点VjVj链成一个链成一个单链表,这个单链表就称为顶点单链表,这个单链表就称为顶点ViVi的邻接表。的邻接表。 邻接表由边表和顶点两部分组成。邻接表由边表和顶点两部分组成。 边表为一个单链表,每个表结点均有两个域:边表为一个单链表,每个表结点均有两个域: 邻接点域邻接点域adjvexadjvex,存放与,存放与vivi相邻接的顶点相邻接的顶点

15、v vj j的序号的序号j j。 链 域链 域 n e x tn e x t , 将 邻 接 表 的 所 有 表 结 点 链 在 一 起 。, 将 邻 接 表 的 所 有 表 结 点 链 在 一 起 。 顶 点 表 为 一 数 组 , 每 个 元 素 均 有 两 个 域 :顶 点 表 为 一 数 组 , 每 个 元 素 均 有 两 个 域 : 顶 点 域顶 点 域 v e r t e xv e r t e x , 存 放 顶 点, 存 放 顶 点 v vi i的 信 息的 信 息 指针域指针域firstedgefirstedge, v vi i的边表的头指针。的边表的头指针。 对于无向图来说,

16、对于无向图来说,ViVi的邻接表中每个表结点都对应于与的邻接表中每个表结点都对应于与ViVi相相关联的一条边,关联的一条边, 对于有向图来说,对于有向图来说,ViVi的邻接表中每个表结点对应于的邻接表中每个表结点对应于ViVi为始点为始点射出的一条边。射出的一条边。 图图7.17.1 图图5-5 图图5-1中(中(1)图的邻接表)图的邻接表 5 51 12 2 图搜索及其术语图搜索及其术语1 1穷举搜索与启发式搜索穷举搜索与启发式搜索 穷举搜索穷举搜索是对图的最基本的搜索算法,是是对图的最基本的搜索算法,是蛮力策略的一种蛮力策略的一种表现形式表现形式。即不考虑给定问题的特有性质,按事先定好的顺

17、序,。即不考虑给定问题的特有性质,按事先定好的顺序,依次运用规则,依次运用规则,盲目搜索盲目搜索的方法。的方法。 启发式搜索启发式搜索是利用一些启发信息,提前判断出先搜索哪些是利用一些启发信息,提前判断出先搜索哪些状态可能尽快找到问题的解或某些情况不可能取到最优解,从状态可能尽快找到问题的解或某些情况不可能取到最优解,从而可以提前舍弃对这些状态的尝试。即考虑给定问题的特有性而可以提前舍弃对这些状态的尝试。即考虑给定问题的特有性质,选用合适的细则,提高搜索的效率。质,选用合适的细则,提高搜索的效率。 2 2相关概念和术语相关概念和术语 问题状态问题状态: :树中的每一个结点确定所求解问题的一个问

18、题状态。树中的每一个结点确定所求解问题的一个问题状态。状态空间状态空间: :由根结点到其它结点的由根结点到其它结点的所有路径所有路径(分支),就确定(分支),就确定 了这个问题的状态空间。了这个问题的状态空间。解状态解状态: :是这样一些问题状态是这样一些问题状态S,对于这些问题状态,由根到,对于这些问题状态,由根到S 的那条路径确定了这解空间中的一个元组。的那条路径确定了这解空间中的一个元组。 答案状态答案状态: :是这样的一些解状态是这样的一些解状态S,对于这些解状态而言,由,对于这些解状态而言,由 根到根到S的这条路径确定了这问题的一个解的这条路径确定了这问题的一个解状态空间树状态空间树

19、: :解空间的树结构解空间的树结构, ,又称隐式图。又称隐式图。 活结点活结点:如果已生成一个结点而它的所有儿子结点还没有:如果已生成一个结点而它的所有儿子结点还没有全部生成,则这个结点叫做活结点。全部生成,则这个结点叫做活结点。 E-结点结点:当前正在生成其儿子结点的活结点叫:当前正在生成其儿子结点的活结点叫E-结点(正结点(正 扩展的结点)。扩展的结点)。死结点死结点 :不再进一步扩展或者其儿子结点已全部生成的生:不再进一步扩展或者其儿子结点已全部生成的生成结点就是死结点成结点就是死结点 。5 52 21 1 算法框架算法框架 1算法的基本思路算法的基本思路 算法设计的基本步骤为算法设计的

20、基本步骤为: 1)确定图的存储方式;)确定图的存储方式; 2)图的遍历过程中的操作,其中包括为输出问题解)图的遍历过程中的操作,其中包括为输出问题解而进行的存储操作;而进行的存储操作; 3 3)输出问题的结论。)输出问题的结论。 2 2算法框架算法框架 从从广度优先搜索定义可以看出活结点的扩展是按先来先处广度优先搜索定义可以看出活结点的扩展是按先来先处理的原则进行的,所以在算法中要用理的原则进行的,所以在算法中要用“队队”来存储每个来存储每个E-E-结点结点扩展出的活结点。为了算法的简洁,抽象地定义:扩展出的活结点。为了算法的简洁,抽象地定义:queuequeue为队列类型,为队列类型,Ini

21、tQueue( ) InitQueue( ) 为队列初始化函数,为队列初始化函数, EnQueue(QEnQueue(Q,k)k)为入队函数,为入队函数,QueueEmpty(Q) QueueEmpty(Q) 为判断队空函数,为判断队空函数,DeQueue(Q) DeQueue(Q) 为出队函数。为出队函数。 实际应用中,用数组或链表实现队列。实际应用中,用数组或链表实现队列。 开辟数组开辟数组visitedvisited记录记录visitedvisited结点的搜索情况。结点的搜索情况。 在算法框架中以输出结点值表示在算法框架中以输出结点值表示“访问访问”。1)邻接表表示图的广度优先搜索算法

22、 int visitedn; /n visitedn; /n 为结点个数为结点个数/ /bfs(int k,graph head) int i; queue Q ; edgenode *p; /定义队列定义队列/ InitQueue(Q); /队列初始化队列初始化/ print(“visit vertex”,k); / 访问源点访问源点vk/ visitedk=1; EnQueue(Q,k); /vk已访问,将其入队。已访问,将其入队。/ while(!QueueEmpty(Q) /队非空则执行队非空则执行/ i=DeQueue(Q); / vi出队为出队为E-结点结点/ p=headi.fi

23、rstedge; /取取vi的边表头指针的边表头指针/ while(pnull) /扩展扩展E-结点结点 / if(visitedp-adjvex=0) /若若vj未访问过未访问过/ print (“visitvertex”,p-adjvex);/访问访问vj/ visitedp-adjvex=1; EnQueue(Q,p-adjvex); /访问过的访问过的vj人队人队/ p=p-next ; /找找vi的下一邻接点的下一邻接点/ 2)邻接矩阵表示的图的广度优先搜索算法bfsm(int k, graph g100,int n) int i,j; CirQueue Q; InitQueue(Q

24、); print (visit vertex, k); /访问源点访问源点vk/ visitedk=1; EnQueue(Q,k); while(not QueueEmpty(Q) i=DeQueue(Q); /vi出队出队/ for(j=0;jn;j+) /扩展结点扩展结点/ if(gij=1 and visitedj=0) print(visit vertex,j); visitedj=1; EnQueue(Q,j); /访问过的访问过的vj人队人队/ 522 广度优先搜索的应用广度优先搜索的应用 【例【例1 1】已知若干个城市的地图,求从一个城市】已知若干个城市的地图,求从一个城市到另一

25、个城市的路径,要求路径中经过的城市最到另一个城市的路径,要求路径中经过的城市最少少 【例【例2 2】走迷宫问题】走迷宫问题 【例【例1 1】已知若干个城市的地图,求从一个城市到另一个】已知若干个城市的地图,求从一个城市到另一个城市的路径,要求路径中经过的城市最少。城市的路径,要求路径中经过的城市最少。 算法设计:算法设计: 图的广度优先搜索类似与树的层次遍图的广度优先搜索类似与树的层次遍历,逐层搜索正好可以尽快找到一个结点历,逐层搜索正好可以尽快找到一个结点与另一个结点相对而言最直接的路径。与另一个结点相对而言最直接的路径。 如图如图5-6表示的是从城市表示的是从城市A到城市到城市H的交通图。

26、的交通图。从图中可以看出,从城市从图中可以看出,从城市A到城市到城市H要经过若干个要经过若干个城市。现要找出一条经过城市最少一条路线。城市。现要找出一条经过城市最少一条路线。 图5-6 表5-1 图5-6的邻接距阵 具体过程如下:具体过程如下: 1 1)将城市)将城市A A(编号(编号1 1)入队,队首)入队,队首qhqh置为置为0 0、队尾、队尾qeqe置为置为1 1。2 2)将队首所指的城市所有可直通的城市入队)将队首所指的城市所有可直通的城市入队( (如果这如果这个城市在队中出现过就不入队个城市在队中出现过就不入队),),然后将队首加然后将队首加1 1,得到,得到新的队首城市。重复以上步

27、骤,直到城市新的队首城市。重复以上步骤,直到城市H H入队为止。入队为止。当搜到城市当搜到城市H H时,搜索结束。时,搜索结束。 3)输出最少城市线路)输出最少城市线路。 数据结构设计:数据结构设计: 1 1)线性数组)线性数组a作为活结点队的存储空间。作为活结点队的存储空间。2 2)队列的每个结点有两个成员:)队列的每个结点有两个成员:ai.city记记录入队的城市,录入队的城市,ai.pre记录该城市的前趋城记录该城市的前趋城市在队列中的下标,这样通过市在队列中的下标,这样通过ai.pre就可以就可以倒推出最短线路。倒推出最短线路。3 3)设置数组)设置数组visited记录已搜索过的城市

28、。记录已搜索过的城市。 算法如下:算法如下:search( )( )qh=0; qe=1;sq1.city=1;sq1.pre=0;visited1=1;qh=0; qe=1;sq1.city=1;sq1.pre=0;visited1=1; while( qhqe) / while( qhqe) /当队不空当队不空/ /qh=qh+1; /qh=qh+1; /结点出队结点出队/ / for(i=1;i=n,i+) /for(i=1;i=n,i+) /扩展结点扩展结点/ / if if (jzsqqh.cityi=1 and visitedi=0jzsqqh.cityi=1 and visite

29、di=0) qe=qe+1; / qe=qe+1; /结点入队结点入队/ /sqqe.city=i;sqqe.pre=qh;visitedqe=1;sqqe.city=i;sqqe.pre=qh;visitedqe=1;if (sqqe.city=8) out( );if (sqqe.city=8) out( ); print(“No avaliable way.”);print(“No avaliable way.”); 算法分析:时间复杂度是算法分析:时间复杂度是O(n);空间复杂性为);空间复杂性为(n2),包括图本身的存储空间和搜索时辅助空间),包括图本身的存储空间和搜索时辅助空间“队

30、队”的存储空间。的存储空间。out( ); /out( ); /输出路径输出路径/ /print(sqqe.city);print(sqqe.city); while(sqqe.pre0)while(sqqe.pre0) qe=sqqe.pre; print(-,sqqe.city); 【例【例2】走迷宫问题】走迷宫问题 迷宫是许多小方格构成的矩形,在每个小方格中有的是墙(图中的迷宫是许多小方格构成的矩形,在每个小方格中有的是墙(图中的“1”1”)有的是路(图中的)有的是路(图中的“0”0”)。走迷宫就是从一个小方格沿上、下、左、)。走迷宫就是从一个小方格沿上、下、左、右四个方向到邻近的方格,

31、当然不能穿墙。设迷宫的入口是在左上角右四个方向到邻近的方格,当然不能穿墙。设迷宫的入口是在左上角(1,1)(1,1),出口是右下角出口是右下角(8,8)(8,8)。根据给定的迷宫,找出一条从入口到出口的路径。根据给定的迷宫,找出一条从入口到出口的路径。 算法设计:算法设计: 从入口开始广度优先搜索可到达的方格入队,再扩展从入口开始广度优先搜索可到达的方格入队,再扩展 队首的方格,直到搜索到出口时算法结束。队首的方格,直到搜索到出口时算法结束。 对于迷宫中任意一点对于迷宫中任意一点A(Y,X),有四个搜索方向:),有四个搜索方向: 向上向上A(Y-1,X) 向下向下A(Y+1,X) 向左向左A(

32、Y,X-1) 向右向右A(Y,X+1) 当对应方格可行(值为当对应方格可行(值为0),就扩展为活结点。),就扩展为活结点。 数据结构设计数据结构设计: 用数组做队的存储空间,队中结点有三个用数组做队的存储空间,队中结点有三个成员:行号、列号、前一个方格在队列中的成员:行号、列号、前一个方格在队列中的下标。搜索过的方格不另外开辟空间记录其下标。搜索过的方格不另外开辟空间记录其访问的情况,而是用迷宫原有的存储空间置访问的情况,而是用迷宫原有的存储空间置元素值为元素值为“-1”-1”时,标识已经访问过该方格。时,标识已经访问过该方格。 为了构造循环体,用数组为了构造循环体,用数组fx=1,-1,0,

33、0fx=1,-1,0,0、fy= 0,0,-1,1 fy= 0,0,-1,1 模拟上下左右搜索时的下标模拟上下左右搜索时的下标的变化过程。的变化过程。 int jz88= 1,0,0,0,1,0,1,1,0,1,1,1,1,0,1,1, 0,1,1,0,0,1,1,1, 0,1,0,1,1,1,0,1, 1,1,0,1,1,1,0,0,0,0,1,1,1,1,1,0, 1,1,1,0,0,1,1,0, 1,1,1,1,0,0,0,1;struct intcity, pre; sq100;int qh,qe,i,visited100;main( )int i,n=8;for(i=1;i=n,i=

34、i+1) visitedi=0;search( );search( )qh=0; qe=1;maze11=-1;Sq1.pre=0;sq1.x=1;sq1.y=1; while( qhqe) /当队不空当队不空/qh=qh+1; /结点出队结点出队/ for(k=1;k=4,k=k+1) /扩展结点扩展结点/i=sqqh.x+fxk;j=sqqh.y+fyk; if(check(i,j)=1) qe =qe+1;sqqe.x=i;sqqe.y=j; sqqe.pre=qh;mazeij=-1; if(sqqe.x =8 and sqqe.y=8) out();return; 检查位置函数检查位

35、置函数Check(int i,int j)int flag = 1;if(i8 or j8) flag =0;/是否在迷宫内是否在迷宫内if(mazeij=1 or mazeij=-1)flag=0;/是否可行是否可行return flag;out( );/输出路径输出路径/print(“(”,sqqe.x,”,”sqqe.y,”)”);while(sqqe.pre0) qe=sqqe.pre; print(-, “(”,sqqe.x,”,”sqqe.y,”)”);算法分析:算法分析: 算法算法的时间复杂度并不复杂是的时间复杂度并不复杂是O O(n n),算法的空间复杂性),算法的空间复杂性为

36、为O O(n n2 2),包括图本身的存储空间和搜索时辅助空间),包括图本身的存储空间和搜索时辅助空间“队队”的的存储空间。存储空间。 输出路径及算法分析输出路径及算法分析 深度优先遍历首先访问出发点深度优先遍历首先访问出发点v v,并将其标记为已,并将其标记为已访问过;然后依次从访问过;然后依次从v v出发搜索出发搜索v v的每个邻接点的每个邻接点w w。若。若w w未未曾访问过,则以曾访问过,则以w w为新的出发点继续进行深度优先遍历,为新的出发点继续进行深度优先遍历,直至图中所有和源点直至图中所有和源点v v有路径相通的顶点均已被访问为有路径相通的顶点均已被访问为止。止。 若此时图中仍有

37、未访问的顶点,则另选一个尚未访若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。点均已被访问为止。5.3 深度优先搜索深度优先搜索 深度搜索与广度搜索的相近,最终都要扩展一个深度搜索与广度搜索的相近,最终都要扩展一个结点的所有子结点结点的所有子结点. . 区别在于对扩展结点过程,深度搜索扩展的是区别在于对扩展结点过程,深度搜索扩展的是E-E-结结点的邻接结点中的一个,并将其作为新的点的邻接结点中的一个,并将其作为新的E-E-结点继续扩结点继续扩展,当前展,当前E-E-结点仍为活结点,待搜

38、索完其子结点后,回结点仍为活结点,待搜索完其子结点后,回溯到该结点扩展它的其它未搜索的邻接结点。而广度搜溯到该结点扩展它的其它未搜索的邻接结点。而广度搜索,则是扩展索,则是扩展E-E-结点的所有邻接结点,结点的所有邻接结点,E-E-结点就成为一结点就成为一个死结点。个死结点。531 算法框架算法框架 1 1算法的基本思路算法的基本思路 2 2算法框架算法框架1算法的基本思路算法的基本思路 算法设计的基本步骤为: 1)确定图的存储方式; 2)遍历过程中的操作,其中包括为输出问题解而进行的存储操作; 3)输出问题的结论。 4)一般在回溯前的应该将结点状态恢复为原始状态,特别是在有多解需求的问题中。

39、2算法框架 1)用邻接表存储图的搜索算法 2)用邻接矩阵存储图的搜索算法graph head100graph head100;dfs(int k) / headdfs(int k) / head图的顶点数组图的顶点数组/ / edgenode edgenode * *ptr / ptrptr / ptr图的边表指针图的边表指针/ / visitedk=1; / visitedk=1; /* * 记录已遍历过记录已遍历过 * */ / print(“ print(“访问访问 ”,k); /,k); /* * 印出遍历顶点值印出遍历顶点值 * */ / ptr=headk.firstedge; /

40、 ptr=headk.firstedge; /* * 顶点的第一个邻接点顶点的第一个邻接点 * */ / while ( ptr NULL ) / while ( ptr NULL ) /* * 遍历至链表尾遍历至链表尾 * */ / if ( visitedptr-vertex=0) / if ( visitedptr-vertex=0) /* * 如果没遍历过如果没遍历过 * */ / dfs(ptr-vertex); / dfs(ptr-vertex); /* * 递归遍历递归遍历 * */ / ptr = ptr-nextnode; / ptr = ptr-nextnode; /* *

41、 下一个顶点下一个顶点 * */ / 算法分析:算法分析:n n图中有图中有 n n 个顶点,个顶点,e e 条边。扫描边的时间为条边。扫描边的时间为O(e)O(e)。遍历图。遍历图的时间复杂性为的时间复杂性为O(n+e)O(n+e)。 ngraph g100100,int ngraph g100100,int n;ndfsm(int k)dfsm(int k) int j int j; print(“ print(“访问访问 ”,k);,k); visitedk=1 visitedk=1; for(j=1 for(j=1;j=nj=n;j+) /j+) /依次搜索依次搜索vkvk的邻接点的邻

42、接点 if(gkj=1 and visitedj=0) if(gkj=1 and visitedj=0) dfsm(g,j) dfsm(g,j) /(vk /(vk,vj)Evj)E,且,且vjvj未访问过,故未访问过,故vjvj为新出发点为新出发点 算法分析:查找每一个顶点的所有的边,所需时间为算法分析:查找每一个顶点的所有的边,所需时间为O(n)O(n),遍,遍历图中所有的顶点所需的时间为历图中所有的顶点所需的时间为O(n2)O(n2)。 532 深度优先搜索的应用深度优先搜索的应用【例1】走迷宫问题:问题同522【例2】1、算法设计、算法设计:深度优先搜索,就是一直向着可通行的下一个方格

43、行进,直到搜索到出口就找到一个解。若行不通时,则返回上一个方格,继续搜索其它方向。2 2、数据结构设计、数据结构设计:我们还是用迷宫本身的存储空间除了记录走过的信息,还要标识是否可行: mazeij=3 标识走过的方格 ; mazeij=2 标识走入死胡同的方格,这样,最后存储为“3”的方格为可行的方格。而当一个方格四个方向都搜索完还没有走到出口,说明该方格或无路可走或只能走入了“死胡同”。3 3、算法、算法int maze88=0,0,0,0,0,0,0,0,int maze88=0,0,0,0,0,0,0,0, 0,11,1,1,0,1,0,0,0,0,0,1,0,1,0, 0,11,1,

44、1,0,1,0,0,0,0,0,1,0,1,0, 0,1,0,0,0,0,1,0,0,1,0,1,1,0,1,0, 0,1,0,0,0,0,1,0,0,1,0,1,1,0,1,0, 0,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0, 0,1,0,0,0,0,1,1,0,1,0,0,1,0,0,0, 0,1,1,1,1,1,1,0;fx4=1,-1,0,0, 0,1,1,1,1,1,1,0;fx4=1,-1,0,0, fy4=0,0,-1,1; int i,j,k,total; fy4=0,0,-1,1; int i,j,k,total;main( )main( ) int tot

45、al=0; int total=0; maze11=3; / maze11=3; /入口坐标设置已走标志入口坐标设置已走标志/ / search(1,1); search(1,1); print(“Total is”,total); / print(“Total is”,total); /统计总步数统计总步数/ / nsearch(int i, int j)search(int i, int j)int k,newi,newj;int k,newi,newj; for(k=1;k=4;k+) / for(k=1;k=4;k+) /搜索可达的方格搜索可达的方格/ / if(check(i,j,k

46、)=1) if(check(i,j,k)=1) newi=i+fxk; newj=j+fyk; newi=i+fxk; newj=j+fyk; mazenewinewj=3; / mazenewinewj=3; /来到新位置后来到新位置后, ,设置已走过标志设置已走过标志/ / if (newi=8 and newj=8) / if (newi=8 and newj=8) /到出口则输出到出口则输出, ,否则下一步递归否则下一步递归/ / Out( ); Out( ); else search(newi,newj); else search(newi,newj); mazeij=2; / ma

47、zeij=2; /某一方格只能走入死胡同某一方格只能走入死胡同/ / nOut( )Out( )n int i,j; int i,j; for( i=1;i=8;i+) for( i=1;i=8;i+) n print(“ print(“换行符换行符”););n for(j=1;j=8;j+) for(j=1;j=8;j+) n if if(mazeij=3mazeij=3) n print(“V”);print(“V”);n total+; / total+; /统计总步数统计总步数/ /n else elsen print(“ print(“* *”);”);n n check(int i

48、,int j,int k)check(int i,int j,int k)int flag=1;int flag=1; i= i+fxk; j= j +fyk; i= i+fxk; j= j +fyk; if(i8 or j8) / if(i8 or j8) /是否在迷宫内是否在迷宫内/ / flag=0; flag=0; else else if(mazeij0) / if(mazeij0) /是否可行是否可行/ / flag=0; flag=0; return(flag); return(flag); 4、算法说明、算法说明:1)和广度优先算法一样每个方格有四个方向可以)和广度优先算法一样

49、每个方格有四个方向可以进行搜索,这样一点结点(方格)就可多次成为进行搜索,这样一点结点(方格)就可多次成为“活结点活结点”,而在广度优先算法一点结点(方格),而在广度优先算法一点结点(方格)就可一次成为就可一次成为“活结点活结点”,一出队就成了死结点。,一出队就成了死结点。2)用广度优先算法,用广度优先算法,搜索出的是搜索出的是一条最短的路径一条最短的路径,而用而用深度优先深度优先搜索则搜索则只能找出一条可行只能找出一条可行的路径,的路径,而不能保证是最短的路径。而不能保证是最短的路径。3)在空间效率上二者相近。都需要辅助空间。)在空间效率上二者相近。都需要辅助空间。 【例【例2】有如图】有如

50、图1所示的七巧板,试编写一源所示的七巧板,试编写一源程序如下,使用至多四种不同颜色对七巧板进行程序如下,使用至多四种不同颜色对七巧板进行涂色涂色(每块涂一种颜色每块涂一种颜色),要求相邻区域的颜色互,要求相邻区域的颜色互不相同,打印输出所有可能的涂色方案。不相同,打印输出所有可能的涂色方案。 n1、问题分析、问题分析:为了让算法能识别不同区域间的相邻关 系,我们把七巧板上每一个区域看成一个顶点若两个区域相邻,则相应的顶点间用一条边相连,这样该问题就转化为图一个图的搜索问题了。2 2、算法设计、算法设计: : 按顺序分别对号、号、按顺序分别对号、号、.、号区域进行、号区域进行试探性涂色,用、号代

51、表种颜色。试探性涂色,用、号代表种颜色。 则涂色过程如下:则涂色过程如下: 1 1)对某一区域涂上与其相邻区域不同的颜色。)对某一区域涂上与其相邻区域不同的颜色。 2 2)若使用种颜色进行涂色均不能满足要求,则)若使用种颜色进行涂色均不能满足要求,则回溯一步,更改前一区域的颜色。回溯一步,更改前一区域的颜色。 3 3)转步骤继续涂色,直到全部区域全部涂色为)转步骤继续涂色,直到全部区域全部涂色为止,输出结果。止,输出结果。 已经有研究证明,对任意的平面图至少存在一种四已经有研究证明,对任意的平面图至少存在一种四色涂色法。色涂色法。3、数据采用的存储结构:邻接矩阵存储 0 1 0 0 1 0 1

52、 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 1 1 1 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 0n4 4、算法如下、算法如下: :nint data77,n,color7,total;int data77,n,color7,total;nmain( )main( )n int i,j; int i,j;n for(i=1;i=n;i+) for(i=1;i=n;i+) n for(j=1;j=n;j+) for(j=1;j=n;j+)n input(dataij); input(dataij);n for(j=1;j=n;

53、j+) for(j=1;j7) if (s7)n output( ); output( ); else else for(i=1;i=4;i+) for(i=1;i=4;i+) colors=i; colors=i; if if (colorsame(s)=0colorsame(s)=0)n try(s+1);try(s+1); n noutput( )output( ) int i,; int i,; print( print(换行符,换行符,serial numberserial number:,total);,total); for i:=1 to n do for i:=1 to n

54、do n print(colori); print(colori); total=total+1; total=total+1;n ncolorsame(int s) /colorsame(int s) /判断相邻点是否同色判断相邻点是否同色/ / int i,flag; int i,flag; flag=0; flag=0; for(i=1;i=s-1;i+) for(i=1;iDFN(3)=3L(10)=4DFN(3)=3。同理,结点。同理,结点2 2、5 5也是也是关结点。关结点。 按后根次序访问深度优先生成树的结点,可按后根次序访问深度优先生成树的结点,可以很容易地算出以很容易地算出L

55、 L(U U)。于是,为了确定图)。于是,为了确定图G G的的关结点关结点, ,必须既完成对必须既完成对G G的深度优先检索,产生的深度优先检索,产生G G的深度优先生成树的深度优先生成树T T,又要按后根次序访问树,又要按后根次序访问树T T的的结点。结点。算法算法ARTART计算计算DFNDFN和和L L的算法如下:的算法如下: int DFNnint DFNn,LnLn,numnum,n n ART ART(u u,v v) /u/u是深度优先检索的开始是深度优先检索的开始结点。在深度优先生成树中,结点。在深度优先生成树中, u u若有父亲,那末若有父亲,那末v v就是它的父亲。假设数组

56、就是它的父亲。假设数组DFNDFN是全程量,并将其初始化为是全程量,并将其初始化为0 0。numnum是全程变是全程变量,被初始化为量,被初始化为 1 1。n n是是 G G的结点数的结点数算法如下:算法如下: int DFNn,Ln,num=1,n;TRY(u,v)DFNu=num;Lu=num;num=num1;while (每个邻接于(每个邻接于u的结点的结点 w ) if (DFN(w)=0) TRY(w,u);); if(L(u)L(w)L(u)=L(w);); else if (wv) if (L(u)DFN(w)) L(u)= DFN(w);); 算法说明:算法说明: 算法算法A

57、RTART实现了对图实现了对图G G的深度优先检索;在的深度优先检索;在检索期间,对每个新访问的结点赋予深度优先数;检索期间,对每个新访问的结点赋予深度优先数;同时对这棵树中每个结点的同时对这棵树中每个结点的L L(i i)值也进行计算。)值也进行计算。 如果连通图如果连通图G G有有n n个结点个结点e e条边,且条边,且G G由邻接由邻接表表示,那末表表示,那末ARTART的计算时间为的计算时间为O O(n ne e)。识别)。识别关结点的总时间不超过关结点的总时间不超过O O(n ne e)。)。3 3非重连通图的加边策略非重连通图的加边策略q G=( V, E )G=( V, E )是

58、是G G的最大重连通子图,指的的最大重连通子图,指的是是G G中再没有这样的重连通子图中再没有这样的重连通子图G=( V, G=( V, E )E )存在,使得存在,使得VVVV且且EEEE。q 最大重连通子图称为重连通分图最大重连通子图称为重连通分图 使用这个方法将图使用这个方法将图5-65-6变成重连通图,需要变成重连通图,需要对应于关结点对应于关结点3 3增加边(增加边(4 4,1010)和()和(1010,9 9););对应关结点对应关结点2 2增加边(增加边(1 1,5 5);对应关结点);对应关结点5 5增加增加(6 6,7 7),结果如图),结果如图5-115-11。 图5-11

59、 (图5-6改进为重连通图)54 回回 溯溯 法法 回溯算法实际是一个类似枚举的搜索尝试方法,它的回溯算法实际是一个类似枚举的搜索尝试方法,它的主题思想是在搜索尝试中找问题的解,当不满足求解条件主题思想是在搜索尝试中找问题的解,当不满足求解条件就就”回溯回溯”返回,尝试别的路径。回溯算法是尝试搜索算返回,尝试别的路径。回溯算法是尝试搜索算法中最为基本的一种算法,其采用了一种法中最为基本的一种算法,其采用了一种“走不通就掉头走不通就掉头”的思想,作为其控制结构。的思想,作为其控制结构。541 认识回溯法【例【例1 1】八皇后问题模型建立】八皇后问题模型建立 要在要在8 8* *8 8的国际象棋棋

60、盘中放八个皇后,使任的国际象棋棋盘中放八个皇后,使任意两个皇后都不能互相吃掉。规则:皇后能吃掉同意两个皇后都不能互相吃掉。规则:皇后能吃掉同一行、同一列、同一对角线的任意棋子。如图一行、同一列、同一对角线的任意棋子。如图5-125-12为一种方案,求所有的解。为一种方案,求所有的解。 模型建立模型建立 不妨设八个皇后为不妨设八个皇后为x xi i,她们分别在第,她们分别在第i i行(行(i=1i=1,2 2,3 3,44,8 8),这样问题的解空间,就是一个),这样问题的解空间,就是一个八个皇后所在列的序号,为八个皇后所在列的序号,为n n元一维向量(元一维向量(x x1 1,x,x2 2,x

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论