族谱网 头条 人物百科

广度优先搜索

2020-10-16
出处:族谱网
作者:阿族小谱
浏览:425
转发:0
评论:0
作法BFS是一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位址,彻底地搜索整张图,直到找到结果为止。BFS并不使用经验法则算法。从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。一般的实现里,其邻居节点尚未被检验过的节点会被放置在一个被称为open的容器中(例如伫列或是链表),而被检验过的节点则被放置在被称为closed的容器中。(open-closed表)实现方法首先将根节点放入队列中。从队列中取出第一个节点,并检验它是否为目标。若队列为空,表示整张图都检查过了——亦即图中没有欲搜寻的目标。结束搜寻并回传“找不到目标”。重复步骤2。C的实现/***ADDQ(Q,p)-pPUSH入Q*DELQ(Q)-POPQ並返回Q頂*FIRSTADJ(G,v)-v的第一個鄰接點,找不到則返回-1*NEXTADJ(G,v)-v的下...

作法

BFS是一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位址,彻底地搜索整张图,直到找到结果为止。BFS并不使用经验法则算法。

从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。一般的实现里,其邻居节点尚未被检验过的节点会被放置在一个被称为 open 的容器中(例如伫列或是链表),而被检验过的节点则被放置在被称为 closed 的容器中。(open-closed表)

实现方法

首先将根节点放入队列中。

从队列中取出第一个节点,并检验它是否为目标。

若队列为空,表示整张图都检查过了——亦即图中没有欲搜寻的目标。结束搜寻并回传“找不到目标”。

重复步骤2。

C 的实现

/*** ADDQ (Q, p) - p PUSH 入 Q* DELQ (Q) - POP Q 並返回 Q 頂* FIRSTADJ (G,v) - v 的第一個鄰接點,找不到則返回 -1* NEXTADJ (G,v) - v 的下一個鄰接點,找不到則返回 -1* VISIT (v) - 訪問 v* visited [] - 是否已訪問*//* 廣度优先搜索算法 */voidBFS(VLinkG[],intv){intw;/* 訪問 v 並入隊 */VISIT(v);visited[v]=1;ADDQ(Q,v);/* 對隊列 Q 的各元素 */while(!EMPTYQ(Q)){v=DELQ(Q);w=FIRSTADJ(G,v);/* 的各鄰接點 */do{/* 進行訪問和入隊 */if(visited[w]==0){VISIT(w);ADDQ(Q,w);visited[w]=1;}}while(w=NEXTADJ(G,v))!=-1)}}/* 對圖G=(V,E)進行廣度優先搜索的主算法 */voidTRAVEL_BFS(VLinkG[],boolvisited[],intn){inti;// 清零標記數組for(i=0;i<n;i++)visited[i]=0;for(i=0;i<n;i++)if(visited[i]==0)BFS(G,i);}

C++ 的实现

(这个例子仅针对Binary Search Tree) 定义一个结构体来表达一个节点的结构:

structnode{intself;//数据node*left;//左节点node*right;//右节点};

那么,我们在搜索一个树的时候,从一个节点开始,能首先获取的是它的两个子节点。例如:

A是第一个访问的,然后顺序是B和C;然后再是B的子节点,C的子节点。那么我们怎么来保证这个顺序呢?

这里就应该用queue数据结构,因为queue采用先进先出( first-in-first-out )的顺序。

使用C++的STL函式库,下面的程序能帮助理解:

std::queuevisited,unvisited;nodenodes[9];node*current;unvisited.push(&nodes[0]);//先把root放入unvisited queuewhile(!unvisited.empty())//只有unvisited不空{current=(unvisited.front());//目前應該檢驗的if(current->left!=NULL)unvisited.push(current->left);//把左邊放入queue中if(current->right!=NULL)//右邊壓入。因為QUEUE是一個先進先出的結構构,所以即使後面再壓其他东西,依然會先訪問這個。unvisited.push(current->right);visited.push(current);cout<self<<endl;unvisited.pop();}

特性

空间复杂度

因为所有节点都必须被储存,因此BFS的空间复杂度为O(|V| + |E|),其中|V|是节点的数目,而|E|是图中边的数目。注:另一种说法称BFS的空间复杂度为 O ( B M ) {\displaystyle O(B^{M})} ,其中B是最大分支系数,而M是树的最长路径长度。由于对空间的大量需求,因此BFS并不适合解非常大的问题。

时间复杂度

最差情形下,BFS必须寻找所有到可能节点的所有路径,因此其时间复杂度为O(|V| + |E|),其中|V|是节点的数目,而|E|是图中边的数目。

完全性

广度优先搜索算法具有完全性。这意指无论图形的种类如何,只要目标存在,则BFS一定会找到。然而,若目标不存在,且图为无限大,则BFS将不收敛(不会结束)。

最佳解

若所有边的长度相等,广度优先搜索算法是最佳解——亦即它找到的第一个解,距离根节点的边数目一定最少;但对一般的图来说,BFS并不一定回传最佳解。这是因为当图形为加权图(亦即各边长度不同)时,BFS仍然回传从根节点开始,经过边数目最少的解;而这个解距离根节点的距离不一定最短。这个问题可以使用考虑各边权值,BFS的改良算法成本一致搜寻法来解决。然而,若非加权图形,则所有边的长度相等,BFS就能找到最近的最佳解。

广度优先搜索算法的应用

广度优先搜索算法能用来解决图论中的许多问题,例如:

寻找图中所有连接元件(Connected Component)。一个连接元件是图中的最大相连子图。

寻找连接元件中的所有节点。

寻找非加权图中任两点的最短路径。

测试一图是否为二分图。

(Reverse)Cuthill–McKee算法

寻找连接元件

由起点开始,执行广度优先搜索算法后所经过的所有节点,即为包含起点的一个连接元件。

测试是否二分图

BFS可以用以测试二分图。从任一节点开始搜寻,并在搜寻过程中给节点不同的标签。例如,给开始点标签0,开始点的所有邻居标签1,开始点所有邻居的邻居标签0……以此类推。若在搜寻过程中,任一节点有跟其相同标签的邻居,则此图就不是二分图。若搜寻结束时这种情形未发生,则此图为一二分图。

应用于电脑游戏中平面网格

BFS可用来解决电脑游戏(例如即时策略游戏)中找寻路径的问题。在这个应用中,使用平面网格来代替图形,而一个格子即是图中的一个节点。所有节点都与它的邻居(上、下、左、右、左上、右上、左下、右下)相接。

值得一提的是,当这样使用BFS算法时,首先要先检验上、下、左、右的邻居节点,再检验左上、右上、左下、右下的邻居节点。这是因为BFS趋向于先寻找斜向邻居节点,而不是四方的邻居节点,因此找到的路径将不正确。BFS应该先寻找四方邻居节点,接着才寻找斜向邻居节点1。

参见

先验算法

深度优先搜索

参考资料

Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein], Introduction to Algorithms , Second Edition. MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7. Section 22.2: Breadth-first search, pp. 531–539.


免责声明:以上内容版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。感谢每一位辛勤著写的作者,感谢每一位的分享。

——— 没有了 ———
编辑:阿族小谱

相关资料

展开
发表评论
写好了,提交
{{item.label}}
{{commentTotal}}条评论
{{item.userName}}
发布时间:{{item.time}}
{{item.content}}
回复
举报
点击加载更多
打赏作者
“感谢您的打赏,我会更努力的创作”
— 请选择您要打赏的金额 —
{{item.label}}
{{item.label}}
打赏成功!
“感谢您的打赏,我会更努力的创作”
返回

更多文章

更多精彩文章
打赏
私信

推荐阅读

· 深度优先搜索
C++的实现定义一个结构体来表达一个NODE的结构:structNode{intself;//数据Node*left;//左节点Node*right;//右节点};那么我们在搜索一个树的时候,从一个节点开始,能首先获取的是它的两个子节点。例如:“ABCDEFG”A是第一个访问的,然后顺序是B和D、然后是E。然后再是C、F、G。那么我们怎么来保证这个顺序呢?这里就应该用堆栈的结构,因为堆栈是一个先进后出的顺序。通过使用C++的STL,下面的程序能帮助理解:constintTREE_SIZE=9;std::stackunvisited;Nodenodes[TREE_SIZE];Node*current;//初始化树for(inti=0;i<TREE_SIZE;i++){nodes[i].self=i;intchild=i*2+1;if(childright);//把右边压入因为右边的访问次序是...
· 搜索
搜索方式按是否使用启发式信息分启发式搜索盲目搜索按问题的表示方式分状态空间搜索与/或树搜索搜索策略宽度优先搜索宽度优先搜索算法是沿着树的宽度遍历树的节点,如果发现目标,则算法中止。属于盲目搜索。深度优先搜索深度优先搜索沿着树的最大深度方向生成节点并与目标节点进行比较,只有当上次访问的节点不是目标节点,而且没有其他节点可以生成的时候,才转到上次访问节点的父节点,然后搜索该节点的其他子节点。因此深度优先搜索也称为回溯搜索。它既不是完备的,也不是最优的。有时候,某些特定的问题会产生大量重复的节点。例如“八数码”问题就是这样的,当每次运用向上、向下、向左、向右移动空格的算符时,可能产生与已经产生的节点重复的节点。当再次搜索到这个重复节点时,由于应用的算符基本一致,还会产生重复,所以为了节约时间和存储空间,往往在深度优先算法中设立一个机制,用来删除这些重复的节点,以提高效率。迭代加深搜索(ID搜索)...
· 优先股
优先股的特征股利优先分派一般而言,优先股在股利分派上具有优先性。股利分派的优先性并不保证股利一定会分派,但如果公司分派普通股股利,则必须分派优先股股利。优先股可以是可累积的或不可累积的。若优先股为可累积优先股,则一旦发行优先股的公司某一期间不分派优先股股利(或只按低于约定的股息率分派),就必须在之后分派,优先股股利在各个不分派或少分派股利的期间不断累积。若优先股为不可累积优先股,则一旦发行优先股的公司某一期间不分派股利,优先股持有者就无法在以后期间获得补偿。优先股的种类是否参加公司利润分配是否可以转换为普通股是否可被公司赎回股息是否可调换
· 园路设计管理优先还是使用优先?
景观设计当中园路的设计十分重要,是连接景点以及各个功能空间的纽带,是整个景观环境的构成骨架。景观设计当中园路的设计有时候使用和管理以及布局美观是有冲突的,究竟是考虑管理优先还是使用优先?是个值得斟酌的问题。考虑管理优先,方便了统一的管理,以最小的管理人力物力投入,达到最大管理能力,比如设置少量的统一入口、单一区域的停车场等等。但这样做虽然管理上是方便了,但也带来了诸多使用上的问题。比如为了管理方便,设置过少的入口,则会造成游客人为的自发开辟最近进入路线的情况,一般人们都有就近原则的心理,选择最短的路线到达想要到达的目的地,如果相隔的不太远有相应的交通通道,一般则会通过通道进入,但这有个度,如果超出了这个度,就会造成适用上的不便。深圳地铁莲花村站A口面对造成人们自发的开辟最近的适用路线的情况,是采用“堵为上”,还是“疏为上”?显然,“堵”并不能解决根本问题,“疏”才为上策。所以景观设计当中园...
· 搜索及拯救
种类搜索及拯救包括了多项小项,包括:地面搜索及拯救(英文:GroundSearchandRescue,缩写:GSAR),通常是于地面或者内陆水道(例如引水道)进行。传统上,此项工作通常于郊区以至荒野区域进行。城市搜索及拯救(英文:UrbanSearchandRescue,缩写:USAR),是于城市或者市区进行,通常有涉及自然灾害(例如山泥倾泻、地震、台风、洪水、受到海啸侵袭的沿海城市等)、交通意外、坍塌事故及矿道等。山岭搜索及拯救(英文:MountainSearchandRescue,缩写:MSAR),是于山上进行。海空拯救(英文:AirSeaResue),是于空中或者海上进行,需要协调飞行器及船只合作进行。战斗搜索及拯救(英文:CombatSearchandRescue,缩写:CSAR),是于战场或战区上进行。等等。历史世界上最早的搜索及拯救纪录可以追溯至1656年,一艘荷兰商业船只(V...

关于我们

关注族谱网 微信公众号,每日及时查看相关推荐,订阅互动等。

APP下载

下载族谱APP 微信公众号,每日及时查看
扫一扫添加客服微信