第八章廣度優先搜索算法_第1頁
第八章廣度優先搜索算法_第2頁
第八章廣度優先搜索算法_第3頁
第八章廣度優先搜索算法_第4頁
第八章廣度優先搜索算法_第5頁
已閱讀5頁,還剩7頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第八章廣度優先搜索算法

廣度優先搜索算法是最簡便的圖的搜索算法之一,這一算法也是很多重要的圖的算法的原型。如Dijkstra單源最短路徑和Prim最小生成樹算法都采用了廣度優先搜索的思想。核心思想:從初始節點開始,應用算符生成第一層節點,檢查目標節點是否在這些后繼節點中,若沒有,再用產生式規則將所有第一層的節點逐一擴展,得到第二層節點,并逐一檢查第二層節點中是否包含目標節點,若沒有,再用算符逐一擴展第二層的所有節點…,如此依次擴展,檢查下去,直到發現目標節點為止。即:1、從圖中的某一頂點v0開始,先訪問v0;2、訪問所有與v0相鄰接的頂點v1、v2…;3、依次訪問與v1、v2…vt相鄰接的所有未曾訪問過的頂點;4、循此以往,直到所有的頂點都被訪問過為止。這種搜索的次序體現了沿層次向橫向擴展的趨勢,所以稱之為廣度優先搜索。

【模塊1】Programbfs;初始化,初始狀態存入隊列;隊列首指針head:=0;尾指針tail:=1;whilehead<taildobegininc(head);指針head后移一位,指向待擴展節點;fori:=1tomaxdobeginif新節點是目標節點then輸出并退出;if新節點符合條件,并且新節點與原已產生的節點不重復thentail指針加1,把新節點加入到隊尾;end;end;算法描述模塊(運用了隊列的結構)

【模塊2】Programbfs;初始化,初始狀態存入隊列;隊列首指針head:=0;尾指針tail:=1;repeatinc(head);指針head后移一位,指向待擴展節點;fori:=1tomaxdobeginif新節點是目標節點then輸出并退出;if新節點符合條件,并且新節點與原已產生的節點不重復thentail指針加1,把新節點加入到隊尾;end;untilhead=tail;end;【廣度優先搜索注意事項】1、每生成一個子節點,就要提供指向它們父親節點的指針。當解出現時候,通過逆向跟蹤,可以找到從根節點到目標節點的一條路徑。(當然不要求輸出路徑的,就沒必要記住父親節點);2、生成的節點要與前面所有已經產生的節點比較,以免出現重復節點,浪費時間和空間,還有可能陷入死循環;3、如果目標節點的深度與費用(如:路徑長度)成正比,那么找到的第一個解即為最優解,這時,搜索速度比深度搜索要快些,在求最優解時往往采用廣度優先搜索;如果節點的費用不與深度成正比時,第一次找到的解不一定是最優解。【算法分析】看圖很容易想到用鄰接矩陣來存儲頂點之間的關系,0表示有通路,即有邊;1表示沒有通路,即沒有邊存在。定義一個a數組,充當存儲擴展節點的隊列,a[i].city記錄經過的城市,a[i].pre記錄前驅城市,這樣就可以倒推出最短線路了,具體過程如下:1、將城市A入隊,隊首指針為0,隊尾指針為1;2、將隊首所指相連的城市依次入隊(注意的是該城市在隊列中未曾出現過),同時將入隊城市的pre指向隊首位置。然后將隊首指針加1,得到新的隊首城市。重復以上操作步驟,直到搜到H城市。利用pre可以倒推出最少城市線路。

例1如圖是從城市A到城市H的交通圖。從圖中可以看出,從城市A到城市H要經過若干個城市。現在要找出一條經過城市最少的一條路線。ABDCGHFE10001111H01100111G01111100F00111011E10111010D11100110C11011110B11010001AHGFEDCBA矩陣存儲頂點關系【參考程序】Programex_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=recordcity:char;pre:integer;end;varhead,tail,i:integer;a:array[1..100]ofnode;s:array[‘A’..’H’]ofboolean;procedureprint(d:integer);beginwrite(a[d].city);repeatd:=a[d].pre;write(‘--------’,a[d].city);untila[d].pre=0;end;Proceduredoit;beginfillchar(s,sizeof(s),true);head:=0;tail:=1;a[1].city:=‘A’;a[1].pre:=0;s[a[1].city]:=false;repeatinc(head);fori:=1to8doif(ju[ord(a[head].city)-64,i]=0)and(s[chr(i+64)]=true)thenbegininc(tail);a[tail].city:=chr(i+64);a[tail].pre:=head;s[a[tail].city]:=false;ifa[tail].city=‘H’thenbeginprint(tail);break;end;end;untilhead=tail;end;Begindoit;End.【算法分析】1、讀入m*n矩陣陣列,將其轉換成為boolean矩陣存入bz數組中;2、沿bz數組矩陣從上到下、從左到右,找到遇到的第一個細胞;3、將細胞的位置入隊h,并沿其上、下、左、右四個方向上的細胞位置入隊,入隊后的位置bz數組置為false;4、將h隊頭出隊,沿其上、下、左、右四個方向上的細胞位置入隊,入隊后的位置bz數組置為false;5、重復4,直到h隊空為止,則此時找到了一個細胞;6、重復2,直至矩陣找不到細胞;7、輸出找到的細胞個數。

例2一矩形陣列由數字0-9組成,數字1-9代表細胞,細胞的定義是沿細胞數字上、下、左、右如果還是細胞數字則為同一細胞,求給定矩形陣列的細胞個數。如陣列:100234500067103456050020456006710000000089【參考程序】programcell;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;n,m,i,j,num:integer;pic:array[1..50,1..50]ofinteger;bz:array[1..50,1..50]ofboolean;h:array[1..1000,1..2]ofinteger;proceduredoit(p,q:integer);vari,t,w,x,y:integer;begininc(num);bz[p,q]:=false;t:=1;w:=1;h[1,1]:=p;h[1,2]:=q;repeatfori:=1to4dobeginx:=h[t,1]+dx[i];y:=h[t,2]+dy[i];if(x>0)and(x<=m)and(y>0)and(y<=n)and(bz[x,y])thenbegininc(w);h[w,1]:=x;h[w,2]:=y;bz[x,y]:=false;end;end;inc(t);untilt>w;end;beginfillchar(bz,sizeof(bz),true);num:=0;readln(m,n);fori:=1tomdobeginreadln(s);forj:=1tondobeginpic[i,j]:=ord(s[j])-48;ifpic[i,j]=0thenbz[i,j]:=false;end;end;fori:=1tomdoforj:=1tondoifbz[i,j]thendoit(i,j);writeln(num);end.上機練習1、最短路徑如圖,從入口(1)到出口(17)的可行路線圖中,數字標號表示關卡。請編程求從入口到出口經過最少關卡路徑的算法。11872341258610911141315161719提示:用鄰接矩陣存儲關卡之間的關系與前驅。【輸出樣例】1716191812、迷宮問題如圖,給一個n*m的迷宮圖和一個入口、一個出口。編程打印一條從迷宮入口到出口的路徑。這里黑色方塊的單元表示走不通(用-1表示),黃色單元表示可以走(用0表示),只能往上、下、左、右四個方向走,如果無路則輸出“Noway!”。(注:只輸出一條就可以了)【提示】本題深搜和廣搜都可以,請同學們動動腦子,有條件的可以兩種方法都試試看。-1-10000000出口00000-1-100-1-1-100000-1-1000-10000-1000000-10入口programexp2;constmaxn=50;dx:array[1..4]ofinteger=(1,0,-1,0);dy:array[1..4]ofinteger=(0,1,0,-1);varmap:array[1..maxn,1..maxn]ofinteger;f:boolean;n,m,i,j,desx,desy,soux,souy,head,tail,x,y,k:integer;route:array[1..maxn]ofrecordx,y,pre:integer;end;procedureprint(d:integer);beginifroute[d].pre<>0thenbeginprint(route[d].pre);inc(k);end;write('(',route[d].x,',',route[d].y,')');end;

beginreadln(n,m);fori:=1tondoforj:=1tomdoread(map[i,j]);readln(soux,souy);readln(desx,desy);

f:=false;k:=1;head:=0;tail:=1;route[1].x:=soux;route[1].y:=souy;route[1].pre:=0;map[soux,souy]:=-1;repeatinc(head);fori:=1to4dobeginx:=route[head].x+dx[i];y:=route[head].y+dy[i];if(x>0)and(x<=n)and(y>0)and(y<=m)and(map[x,y]=0)thenbegininc(tail);route[tail].x:=x;route[tail].y:=y;route[tail].pre:=head;map[x,y]:=-1;if(x=desx)and(y=desy)thenbeginf:=true;print(tail);b

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論