广度宽度优先搜索_第1页
广度宽度优先搜索_第2页
广度宽度优先搜索_第3页
广度宽度优先搜索_第4页
广度宽度优先搜索_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

广度宽度优先搜索第一页,共三十九页,2022年,8月28日深度搜索与广度搜索区分[深度搜索与广度搜索]深度搜索与广度搜索的区别:深度搜索下一次扩展的是本次扩展出来的子节点中的一个,而广度搜索扩展的则是本次扩展的节点的兄弟节点。在具体实现上为了提高效率,所以采用了不同的数据结构。广度搜索是求解最优解的一种较好的方法,而深度搜索多用于只要求解,并且解答树中的重复节点较多并且重复较难判断时使用,但往往可以用回溯算法代替。第二页,共三十九页,2022年,8月28日一些基本概念节点:记录扩展的状态。弧/边:记录扩展的路径。搜索树:描述搜索扩展的整个过程。节点的耗散值 令C(i,j)为从节点ni到nj的这段路径(或者弧)的耗散值,一条路径的耗散值就等于连接这条路径各节点间所有弧的耗散值总和。可以用递归公式描述如下:

C(ni,t)=C(ni,nj)+C(nj,t)4搜索树根节点叶子节点4,5,6,7,88123567第三页,共三十九页,2022年,8月28日广度优先搜索的过程

广度优先搜索算法(又称宽度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。广度优先算法的核心思想是:从初始节点开始,应用算符生成第一层节点,检查目标节点是否在这些后继节点中,若没有,再用产生式规则将所有第一层的节点逐一扩展,得到第二层节点,并逐一检查第二层节点中是否包含目标节点。若没有,再用算符逐一扩展第二层的所有节点……,如此依次扩展,检查下去,直到发现目标节点为止。即⒈从图中的某一顶点V0开始,先访问V0;⒉访问所有与V0相邻接的顶点V1,V2,......,Vt;⒊依次访问与V1,V2,......,Vt相邻接的所有未曾访问过的顶点;⒋循此以往,直至所有的顶点都被访问过为止。这种搜索的次序体现沿层次向横向扩长的趋势,所以称之为广度优先搜索。第四页,共三十九页,2022年,8月28日广度搜索策略综合数据库(变量设置)

与问题相关的所有数据元素构成的集合,用来表述问题状态或有关事实。产生式规则 构建了综合数据库以后,还需要研究问题的移动规则,称为产生式规则。搜索策略 搜索策略的实质是确定如何选取规则的方式。有两种基本方式:一种是不考虑给定问题所具有的特定知识,系统根据事先确定好某种固定顺序,依次调用规则或随机调用规则,这实际上是盲目搜索的方法。另一种是考虑问题领域可应用的知识,动态地确定规则的排列次序,优先调用较合适的规则使用,这就是通常所说的启发式搜索策略。第五页,共三十九页,2022年,8月28日广度优先搜索算法描述:Programbfs;初始化,初始状态存入队列;队列首指针head:=0;尾指针tail:=1;repeat

指针head后移一位,指向待扩展结点;

fori:=1tomaxdobegin//max为产生子结点的规则数if子结点符合条件thenbegintail指针增1,把新结点存入列尾;

if新结点与原已产生结点重复then删去该结点(取消入队,tail减1)

elseif新结点是目标结点then输出并退出;end;end;until(head>=tail);//队列为空第六页,共三十九页,2022年,8月28日广度优先搜索注意事项1、每生成一个子结点,就要提供指向它们父亲结点的指针。当解出现时候,通过逆向跟踪,找到从根结点到目标结点的一条路径。当然不要求输出路径,就没必要记父亲。

2、生成的结点要与前面所有已经产生结点比较,以免出现重复结点,浪费时间,还有可能陷入死循环。

3、如果目标结点的深度与“费用”(如:路径长度)成正比,那么,找到的第一个解即为最优解,这时,搜索速度比深度搜索要快些,在求最优解时往往采用广度优先搜索;如果结点的“费用”不与深度成正比时,第一次找到的解不一定是最优解。

4、广度优先搜索的效率还有赖于目标结点所在位置情况,如果目标结点深度处于较深层时,需搜索的结点数基本上以指数增长。第七页,共三十九页,2022年,8月28日八数码问题

在3*3组成的九宫格棋盘上,摆有八个将牌,每一个将牌都刻有1—8中的某一个数码。棋盘中留有一个空格,允许其周围的某一个将牌向空格中移动,如图1所示。这样通过移动将牌就可以不断改变的布局结构,给出一个初始布局(称初始状态)和一个目标布局(称目标状态),问如何移动将牌,才能实现从初始状态到目标状态的转换。

下面我们看看怎样用宽度优先搜索来解决八数码问题。图2给出广度优先搜索应用于八数码难题时所生成的搜索树。搜索树上的所有结点都标记它们所对应的状态,每个结点旁边的数字表示结点扩展的顺序。粗线条路径表明求得的一个解。从图中可以看出,扩展第26个结点,总共生成46个结点之后,才求得这个解。此外,直接观察此图表明,不存在有更短走步序列的解。第八页,共三十九页,2022年,8月28日八数码问题扩展搜索树

第九页,共三十九页,2022年,8月28日综合数据库(变量设置){Pxy},其中1<=x,y<=3,Pxy∈{0,1,2,3,4,5,6,7,8},且Pxy互不相等

用Pascal语言描述如下:typet8no=array[1..3,1..3]oflongint;{棋盘状态}tList=record{描述一个节点}Father:longint;

{父指针}dep:longint;

{深度}x,y:longint; {空格的位置}state:t8no;

end;const

Max=10000;vars,t:t8no;{s为初始状态,t为目标状态}List:array[0..max]oftList;{综合数据库}第十页,共三十九页,2022年,8月28日产生式规则(关系)if条件then规则;设Pxy表示将牌第x行第y列的数码,m,n表示数码空格所在的行列值,记Pm,n=0,则可以得到如下四条规则:

①ifn-1>=1thenbeginPm,n:=Pm,n-1­

;Pm,n-1­

­:=0end;②ifm-1>=1thenbeginPm,n:=Pm-1,n;Pm-1,n:=0end;③ifn+1<=3thenbeginPm,n:=Pm,n+1;Pm,n+1:=0end;④ifm+1<=3thenbeginPm,n:=Pm+1­,n;Pm+1­,n:=0end;ConstDir:array[1..4,1..2]oflongint{对应四种产生式规则}=((1,0),(-1,0),(0,1),(0,-1));第十一页,共三十九页,2022年,8月28日控制策略

PROCEDUREProduction-System;DATA初始化数据库Repeat

在规则集中选择某一条可作用于DATA的规则R

DATAR作用于DATA后得到的结果

UntilDATA满足结束条件第十二页,共三十九页,2022年,8月28日八数码问题宽度优先算法框架List[1]=source;closed:=0;open:=1;{加入初始节点,List为扩展节点的表}Repeatclosed:=closed+1;n:=List[closed];{取出closed对应的节点}Forx:=1to4dobeginnew:=move(n,4);{对n节点使用第x条规则,得到new}ifnot_appear(new,List)thenbegin{如果new没有在List中出现}open:=open+1;List[open]:=new;{加入新节点到open}List[open].Father:=closed;{修改指针}ifList[open]=GoalthenGetOut;end;enduntilclosed<open;第十三页,共三十九页,2022年,8月28日八数码参考程序(宽度优先)program8no_bfs;{八数码的宽度优先搜索算法}Constdir:array[1..4,1..2]oflongint

{四种移动方向,对应产生式规则}=((1,0),(-1,0),(0,1),(0,-1));n=10000;TypeT8no=array[1..3,1..3]oflongint;TList=recordFather:longint;

{父指针}dep:longint;

{深度}X0,Y0:longint; {0的位置}State:T8no;

{棋盘状态}end;VarSource,Target:T8no;List:array[0..10000]ofTList;{综合数据库}Closed,open,Best:integer{Best表示最优移动次数}Answer:integer;{记录解}Found:Boolean;{解标志}第十四页,共三十九页,2022年,8月28日procedureGetInfo;{读入初始和目标节点}vari,j:integer;beginfori:=1to3doforj:=1to3doread(Source[i,j]);fori:=1to3doforj:=1to3doread(Target[i,j]);end;procedureInitialize;{初始化}varx,y:integer;beginFound:=false;Closed:=0;open:=1;withList[1]dobeginState:=Source;dep:=0;Father:=0;Forx:=1to3doFory:=1to3doifState[x,y]=0thenBeginx0:=x;y0:=y;End;end;end;第十五页,共三十九页,2022年,8月28日functionnot_Appear(new:tList):boolean;{判断new是否在List中出现}vari:integer;beginnot_Appear:=false;fori:=1toopendoifSame(new.State,List[i].State)thenexit;not_Appear:=true;end;procedureMove(n:tList;d:integer;varok:boolean;varnew:tList);{将第d条规则作用于n得到new,OK是new是否可行的标志}varx,y:integer;beginX:=n.x0+Dir[d,1];Y:=n.y0+Dir[d,2];{判断new的可行性}ifnot((X>0)and(X<4)and(Y>0)and(Y<4))thenbeginok:=false;exitend;OK:=true;FunctionSame(A,B:T8no):Boolean;{判断A,B状态是否相等}Vari,j:integer;BeginSame:=false;Fori:=1to3doforj:=1to3doifA[i,j]<>B[i,j]thenexit;Same:=true;End;第十六页,共三十九页,2022年,8月28日new.State:=n.State;{new=Expand(n,d)}new.State[X,Y]:=0;new.State[n.x0,n.y0]:=n.State[X,Y];new.X0:=X;new.Y0:=Y;end;procedureAdd(new:tList);{插入节点new}beginifnot_Appear(new)thenBegin{如果new没有在List出现}Inc(open);{new加入open表}List[open]:=new;end;end;第十七页,共三十九页,2022年,8月28日procedureExpand(Index:integer;varn:tList);{扩展n的子节点}vari:integer;new:tList;OK:boolean;BeginifSame(n.State,Target)thenbegin{如果找到解}Found:=true;Best:=n.Dep;Answer:=Index;Exit;end;Fori:=1to4dobegin{依次使用4条规则}Move(n,i,OK,new);ifnotokthencontinue;new.Father:=Index;new.Dep:=n.dep+1;Add(new);end;end;

第十八页,共三十九页,2022年,8月28日procedureGetOutInfo;{输出}procedureOutlook(Index:integer);{递归输出每一个解}vari,j:integer;beginifIndex=0thenexit;Outlook(List[Index].Father);withList[Index]dofori:=1to3dobeginforj:=1to3dowrite(State[i,j],'');writeln;end;writeln;end;beginWriteln('Total=',Best);Outlook(Answer);end;第十九页,共三十九页,2022年,8月28日procedureMain;{搜索主过程}beginRepeatInc(Closed);Expand(Closed,List[Closed]);{扩展Closed}Until(Closed>=open)orFound;ifFoundthenGetOutInfo{存在解}elseWriteln('noanswer');{无解}end;beginAssign(Input,'input.txt');ReSet(Input);Assign(Output,'Output.txt');ReWrite(Output);GetInfo;Initialize;Main;Close(Input);Close(Output);End.第二十页,共三十九页,2022年,8月28日【例1】图4表示的是从城市A到城市H的交通图。从图中可以看出,从城市A到城市H要经过若干个城市。现要找出一条经过城市最少的一条路线。第二十一页,共三十九页,2022年,8月28日【算法分析】看到这图很容易想到用邻接距阵来表示,0表示能走,1表示不能走。如图。

首先想到的是用队列的思想。a数组是存储扩展结点的队列,a[i].city记录经过的城市,a[i].pre记录前趋城市,这样就可以倒推出最短线路。具体过程如下:(1)将城市A入队,队首为0、队尾为1。(2)将队首所指的城市所有可直通的城市入队(如果这个城市在队列中出现过就不入队,可用一个集合来判断),将入队城市的pre指向队首的位置。然后将队首加1,得到新的队首城市。重复以上步骤,直到搜到城市H时,搜索结束。利用pre可倒推出最少城市线路。第二十二页,共三十九页,2022年,8月28日【参考程序】ProgramEx8_1;constju:array[1..8,1..8]of0..1=((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));

typenode=record//记录定义

city:char;

pre:integer;

end;

varhead,tail,i:integer;

a:array[1..100]ofnode;

s:setof'A'..'H';procedureout(d:integer);//输出过程

begin

write(a[d].city);repeat

d:=a[d].pre;write('--',a[d].city);

untila[d].pre=0;

writeln;

end;第二十三页,共三十九页,2022年,8月28日proceduredoit;

begin

head:=0;tail:=1;

a[1].city:=‘A’;

a[1].pre:=0;

s:=[‘A’];

repeat//步骤2

inc(head);//队首加一,出队

fori:=1to8do//搜索可直通的城市

if(ju[ord(a[head].city)-64,i]=0)and(not(chr(i+64)ins))thenbegin//判断城市是否走过

inc(tail);//队尾加一,入队

a[tail].city:=chr(64+i);

a[tail].pre:=head;

s:=s+[a[tail].city];

ifa[tail].city='H'thenbeginout[tail];break;end;

end;

untilhead=tail;

end;BEGIN//主程序doit;END.输出:

H--F--A第二十四页,共三十九页,2022年,8月28日【例2】一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如:阵列4100234500067103456050020456006710000000089有4个细胞。【算法分析】⑴从文件中读入m*n矩阵阵列,将其转换为boolean矩阵存入bz数组中;

⑵沿bz数组矩阵从上到下,从左到右,找到遇到的第一个细胞;

⑶将细胞的位置入队h,并沿其上、下、左、右四个方向上的细胞位置入队,入队后的位置bz数组置为FLASE;⑷将h队的队头出队,沿其上、下、左、右四个方向上的细胞位置入队,入队后的位置bz数组置为FLASE;

⑸重复4,直至h队空为止,则此时找出了一个细胞;

⑹重复2,直至矩阵找不到细胞;

⑺输出找到的细胞数。

第二十五页,共三十九页,2022年,8月28日programEx8_2;constdx:array[1..4]of-1..1=(-1,0,1,0);

dy:array[1..4]of-1..1=(0,1,0,-1);

varname,s:string;

pic:array[1..50,1..79]ofinteger;

bz:array[1..50,1..79]ofboolean;

m,n,i,j,num:integer;

h:array[1..4000,1..2]ofinteger;

proceduredoit(p,q:integer);

vari,t,w,x,y:integer;

begin

inc(num);bz[p,q]:=false;

t:=1;w:=1;h[1,1]:=p;h[1,2]:=q;//遇到的第一个细胞入队

repeat

fori:=1to4do//沿细胞的上下左右四个方向搜索细胞

begin

x:=h[t,1]+dx[i];y:=h[t,2]+dy[i];

if(x>0)and(x<=m)and(y>0)and(y<=n)andbz[x,y]

thenbegininc(w);h[w,1]:=x;h[w,2]:=y;bz[x,y]:=false;end;end;//本方向搜索到细胞就入队

inc(t);//队头指针加1untilt>w;//直至队空为止

end;第二十六页,共三十九页,2022年,8月28日begin

fillchar(bz,sizeof(bz),true);num:=0;readln(m,n);

fori:=1tomdo

beginreadln(s);

forj:=1tondo

beginpic[i,j]:=ord(s[j])-ord(‘0’);

ifpic[i,j]=0thenbz[i,j]:=false;

end;

end;

fori:=1tomdoforj:=1tondoifbz[i,j]thendoit(i,j);//在矩阵中寻找细胞

writeln('NUMBERofcells=',num);readln;end.第二十七页,共三十九页,2022年,8月28日【例3】最短路径(1995年高中组第4题)如下图所示,从入口(1)到出口(17)的可行路线图中,数字标号表示关卡。现将上面的路线图,按记录结构存储如下图6:请设计一种能从存储数据中求出从入口到出口经过最少关卡路径的算法。第二十八页,共三十九页,2022年,8月28日【算法分析】

该题是一个路径搜索问题,根据图示,从入口(1)到出口(17)可能有多条途径,其中最短的路径只有一条,那么如何找最短路径呢?根据题意,用数组NO存储各关卡号,用数组PRE存储访问到某关卡号的前趋关卡号。其实本题是一个典型的图的遍历问题,我们可以采用图的广度优先遍历,并利用队列的方式存储顶点之间的联系。从入口(1)开始先把它入队,然后把(1)的所有关联顶点都入队,即访问一个顶点,将其后继顶点入队,并存储它的前趋顶点,……,直到访问到出口(17)。最后,再从出口的关卡号(17)开始回访它的前趋关卡号,……,直到入口的关卡号(1),则回访的搜索路径便是最短路径。从列表中可以看出出口关卡号(17)的被访问路径最短的是:(17)←(16)←(19)←(18)←(1)由此,我们得到广度优先遍历求最短路径的基本方法如下:假设用邻接矩阵存放路线图(a[I,j]=1表示I与j连通,a[I,j]=0表示I与j不连通)。再设一个队列和一个表示拓展到哪个顶点的指针变量pos。(1)从入口开始,先把(1)入队,并且根据邻接矩阵,把(1)的后继顶点全部入队,并存储这些后继顶点的前趋顶点为(1);再把pos后移一个,继续拓展它,将其后继顶点入队,并存储它们的前趋顶点,……,直到拓展到出口(目的地(17));

第二十九页,共三十九页,2022年,8月28日

注意后继顶点入队前,必须要检查这个顶点是否已在队列中,如果已经在了就不要入队了;这一步可称为图的遍历或拓展;(2)从队列的最后一个关卡号(出口(17))开始,依次回访它的前驱顶点,倒推所得到的路径即为最短路径。主要是依据每个顶点的前趋顶点倒推得到的。实现如下:

I:=1;

WHILENO[I]<>17DOI:=I+1;REPEATWRITE(‘(‘,NO[I],’)’);WRITE(‘←’);I:=PRE[I];UNTILI=0;【参考程序】留给同学们完成,文件名ex8_3.pas。第三十页,共三十九页,2022年,8月28日【例4】迷宫问题如下图所示,给出一个N*M的迷宫图和一个入口、一个出口。编一个程序,打印一条从迷宫入口到出口的路径。这里黑色方块的单元表示走不通(用-1表示),白色方块的单元表示可以走(用0表示)。只能往上、下、左、右四个方向走。如果无路则输出“noway.”。入口→0-1000000-10000-1000-1-100000-1-1-100-1-100000→出口0000000-1-1【算法分析】只要输出一条路径即可,所以是一个经典的回溯算法问题,本例给出了回溯(深搜)程序和广搜程序。实现见参考程序。第三十一页,共三十九页,2022年,8月28日【深搜参考程序】programEX8_4_1;constmaxn=50;varmap:array[1..maxn,1..maxn]ofinteger;f:boolean;n,m,i,j,desx,desy,soux,souy,totstep:integer;route:array[1..maxn]ofrecordx,y:integer;end;proceduremove(x,y,step:integer);beginmap[x,y]:=step;//走一步,作标记,把步数记下来

route[step].x:=x;route[step].y:=y;//记路径

if(x=desx)and(y=desy)thenbeginf:=true;totstep:=step;endelsebeginif(y<>m)and(map[x,y+1]=0)thenmove(x,y+1,step+1);//向右

ifnotfand(x<>n)and(map[x+1,y]=0)thenmove(x+1,y,step+1);//往下

ifnotfand(y<>1)and(map[x,y-1]=0)thenmove(x,y-1,step+1);//往左

ifnotfand(x<>1)and(map[x-1,y]=0)thenmove(x-1,y,step+1);//往上

end;end;第三十二页,共三十九页,2022年,8月28日BEGINreadln(n,m);//n行m列的迷宫

fori:=1tondo//读入迷宫,0表示通,-1表示不通

beginforj:=1tomdoread(map[i,j]);readln;end;write('inputtheenter:');readln(soux,souy);//入口

write('inputtheexit:');readln(desx,desy);//出口

f:=false;//f=false表示无解;f=true表示找到了一个解

move(soux,souy,1);iffthenfori:=1tototstepdo //输出直迷宫的路径

write(route[i]:4);elsewriteln('noway.');END.第三十三页,共三十九页,2022年,8月28日【广搜参考程序】programEX8_4_2;constmaxn=50;u:array[1..4]ofinteger=(0,1,0,-1);w:array[1..4]ofinteger=(1,0,-1,0);varmap:array[1..maxn,1..maxn]ofinteger;f:boolean;n,m,i,j,desx,desy,soux,souy,head,tail,x,y:integer;route:array[1..maxn]ofrecordx,y,pre:integer;end;procedureprint(d:integer);beginifroute[d].pre<>0thenprint(route[d].pre);write('(',route[d].x,',',route[d].y,')');end;BEGINreadln(n,m);//n行m列的迷宫

fori:=1tondo//读入迷宫,0表示通,-1表示不通

beginforj:=1tomdoread(map[i,j]);readln;end;write('inputtheenter:');readln(soux,souy);//入口第三十四页,共三十九页,2022年,8月28日write('inputtheexit:');readln(desx,desy);//出口

head:=0;tail:=1;f:=false;map[soux,souy]:=-1;route[tail].x:=soux;route[tail].y:=souy;route[tail].pre:=0;whilehead<>taildo //队列不为空

begininc(head);fori:=1to4do //4个方向

beginx:=route[head].x+u[i];y:=route[head].y+w[i];if(x>0)and(x<=n)and(y>0)and(y<=m)and(map[x,y]=0) then begin //本方向上可以走

inc(tail);route[tail].x:=x;route[tail].y:=y;route[tail].pre:=head;map[x,y]:=-1;if(x=desx)and(y=desy)then //扩展出的结点为目标结点

beginf:=true;print(tail);break;end;end;end;iffthenbreak;end;ifnotfthenwriteln('noway!');END.第三十五页,共三十九页,2022年,8月28日输入1:输出1:输入2

温馨提示

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

评论

0/150

提交评论