數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)-迷宮問題_第1頁
數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)-迷宮問題_第2頁
數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)-迷宮問題_第3頁
數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)-迷宮問題_第4頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、.實(shí)驗(yàn)報(bào)告實(shí)驗(yàn)課名稱: 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)實(shí)驗(yàn)名稱: 迷宮問題班級(jí): 20130613學(xué)號(hào): 16:施洋時(shí)間: 2015-5-18一、問題描述這是心理學(xué)中的一個(gè)經(jīng)典問題。 心理學(xué)家把一只老鼠從一個(gè)無頂蓋的大盒子的入口處放入,讓老鼠自行找到出口出來。 迷宮中設(shè)置很多障礙阻止老鼠前行,迷宮唯一的出口處放有一塊奶酪,吸引老鼠找到出口。簡(jiǎn)而言之,迷宮問題是解決從布置了許多障礙的通道中尋找出路的問題。本題設(shè)置的迷宮如圖1 所示。入口出口圖 1 迷宮示意圖迷宮四周設(shè)為墻;無填充處,為可通處。設(shè)每個(gè)點(diǎn)有四個(gè)可通方向,分別為東、南、西、北。左上角為入口。右下角為出口。迷宮有一個(gè)入口,一個(gè)出口。設(shè)計(jì)程序求解迷宮的一條

2、通路。二、數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)以一個(gè) m×n 的數(shù)組 mg表示迷宮,每個(gè)元素表示一個(gè)方塊狀態(tài),數(shù)組元素0 和 1.分別表示迷宮中的通路和障礙。迷宮四周為墻, 對(duì)應(yīng)的迷宮數(shù)組的邊界元素均為1。根據(jù)題目中的數(shù)據(jù),設(shè)置一個(gè)數(shù)組mg如下int mgM+2N+2=1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1; 在算法中用到的棧采用順序存儲(chǔ)結(jié)構(gòu),將棧定義為Struct int i; /當(dāng)前方塊的行號(hào)int j; /當(dāng)前方塊的列號(hào)int di; /di是下一個(gè)相

3、鄰的可走的方位號(hào)stMaxSize;/定義棧int top=-1/初始化棧三、算法設(shè)計(jì)要尋找一條通過迷宮的路徑, 就必須進(jìn)行試探性搜索, 只要有路可走就前進(jìn)一步,無路可進(jìn),換一個(gè)方向進(jìn)行嘗試;當(dāng)所有方向均不可走時(shí),則沿原路退回一步(稱為回溯),重新選擇未走過可走的路,如此繼續(xù),直至到達(dá)出口或返回.入口(沒有通路)。在探索前進(jìn)路徑時(shí),需要將搜索的蹤跡記錄下來,以便走不通時(shí),可沿原路返回到前一個(gè)點(diǎn)換一個(gè)方向再進(jìn)行新的探索。后退的嘗試路徑與前進(jìn)路徑正好相反,因此可以借用一個(gè)棧來記錄前進(jìn)路徑。方向:每一個(gè)可通點(diǎn)有4 個(gè)可嘗試的方向, 向不同的方向前進(jìn)時(shí), 目的地的坐標(biāo)不同。預(yù)先把4 個(gè)方向上的位移存在

4、一個(gè)數(shù)組中。如把上、右、下、左(即順時(shí)針方向)依次編號(hào)為0、1、2、3. 其增量數(shù)組 move4 如圖 3 所示。move4xy0-1010121030-1圖 2 數(shù)組 move4方位示意圖如下:.通路:通路上的每一個(gè)點(diǎn)有3 個(gè)屬性:一個(gè)橫坐標(biāo)屬性i 、一個(gè)列坐標(biāo)屬性j 和一個(gè)方向?qū)傩詃i ,表示其下一點(diǎn)的位置。 如果約定嘗試的順序?yàn)樯稀?右、下、左(即順時(shí)針方向),則每嘗試一個(gè)方向不通時(shí),di 值增 1,當(dāng) d 增至 4 時(shí),表示此位置一定不是通路上的點(diǎn),從棧中去除。 在找到出口時(shí), 棧中保存的就是一條迷宮通路。( 1)下面介紹求解迷宮( xi,yj )到終點(diǎn)( xe,ye )的路徑的函數(shù):

5、先將入口進(jìn)棧(其初始位置設(shè)置為 1),在棧不空時(shí)循環(huán)取棧頂方塊(不退棧) 若該方塊為出口,輸出所有的方塊即為路徑,其代碼和相應(yīng)解釋如下:int mgpath(int xi,int yi,int xe,int ye)/求解路徑為 :(xi,yi)->(xe,ye)structint i;/ 當(dāng)前方塊的行號(hào)int j;/ 當(dāng)前方塊的列號(hào)int di;/di是下一可走方位的方位號(hào) stMaxSize;/ 定義棧int top=-1;/ 初始化棧指針int i,j,k,di,find;top+;/ 初始方塊進(jìn)棧sttop.i=xi;sttop.j=yi;sttop.di=-1;mg11=-1;.

6、while (top>-1)/ 棧不空時(shí)循環(huán)i=sttop.i;j=sttop.j;di=sttop.di; /取棧頂方塊if (i=xe && j=ye)/ 找到了出口 , 輸出路徑printf("迷宮路徑如下 :n");for (k=0;k<=top;k+)printf("t(%d,%d)",stk.i,stk.j);if (k+1)%5=0)/ 每輸出每 5 個(gè)方塊后換一行printf("n");printf("n");return(1);/ 找到一條路徑后返回1 否則,找下一個(gè)可

7、走的相鄰方塊若不存在這樣的路徑,說明當(dāng)前的路徑不可能走通,也就是恢復(fù)當(dāng)前方塊為0 后退棧。若存在這樣的方塊, 則其方位保存在棧頂元素中,并將這個(gè)可走的相鄰方塊進(jìn)棧(其初始位置設(shè)置為-1 )求迷宮回溯過程如圖4 所示.從前一個(gè)方塊找到相鄰可走方塊之后,再?gòu)漠?dāng)前方塊找在、相鄰可走方塊, 若沒有這樣的方快, 說明當(dāng)前方塊不可能是從入口路徑到出口路徑的一個(gè)方塊,則從當(dāng)前方塊回溯到前一個(gè)方塊,繼續(xù)從前一個(gè)方塊找可走的方塊。為了保證試探的可走的相鄰方塊不是已走路徑上的方塊,如( i,j)已經(jīng)進(jìn)棧, 在試探( i+1 , j )的下一方塊時(shí),又試探道( i , j ),這樣會(huì)很悲劇的引起死循環(huán),為此,在一個(gè)

8、方塊進(jìn)棧后,將對(duì)應(yīng)的 mg數(shù)組元素的值改為 -1 (變?yōu)椴豢勺叩南噜彿綁K) ,當(dāng)退棧時(shí) (表示該方塊沒有相鄰的可走方塊) ,將其值恢復(fù) 0,其算法代碼和相應(yīng)的解釋如下: find=0;while (di<4 && find=0)/ 找下一個(gè)可走方塊di+;switch(di)case 0:i=sttop.i-1;j=sttop.j;break;case 1:i=sttop.i;j=sttop.j+1;break;case 2:i=sttop.i+1;j=sttop.j;break;case 3:i=sttop.i,j=sttop.j-1;break;if (mgij=0)

9、 find=1;/找到下一個(gè)可走相鄰方塊if (find=1)/找到了下一個(gè)可走方塊sttop.di=di;/修改原棧頂元素的 di 值top+;/下一個(gè)可走方塊進(jìn)棧sttop.i=i;sttop.j=j;sttop.di=-1;mgij=-1;/避免重復(fù)走到該方塊.else/ 沒有路徑可走 , 則退棧mgsttop.isttop.j=0;/讓該位置變?yōu)槠渌窂娇勺叻綁Ktop-;/ 將該方塊退棧return(0);/ 表示沒有可走路徑, 返回 0(2)求解主程序建立主函數(shù)調(diào)用上面的算法,將mg和 st 棧指針定義為全局變量void main()mgpath(1,1,M,N);四、界面設(shè)計(jì)設(shè)計(jì)很

10、簡(jiǎn)單的界面,輸出路徑。五、運(yùn)行測(cè)試與分析圖 5. 基本運(yùn)行結(jié)果六、實(shí)驗(yàn)收獲與思考思考:8 個(gè)方向的問題1. 設(shè)計(jì)思想.(1) 設(shè)置一個(gè)迷宮節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)。(2) 建立迷宮圖形。(3) 對(duì)迷宮進(jìn)行處理找出一條從入口點(diǎn)到出口點(diǎn)的路徑。(4) 輸出該路徑。(5) 打印通路迷宮圖。初始化迷宮通過隨機(jī)方法設(shè)置迷宮布局建立并輸出迷宮原圖搜索迷宮通路輸出迷宮通路及路線圖結(jié)束圖 6 功能結(jié)構(gòu)圖當(dāng)迷宮采用二維數(shù)組表示時(shí), 老鼠在迷宮任一時(shí)刻的位置可由數(shù)組的行列序號(hào) i ,j 來表示。而從 i,j位置出發(fā)可能進(jìn)行的方向見下圖7. 如果 i,j周圍的位置均為 0 值,則老鼠可以選擇這8 個(gè)位置中的任一個(gè)作為它的下一

11、位置。將這 8 個(gè)方向分別記作: E(東)、 SE(東南)、S(南) SW(西南) W(西)、NW(西北)、N(北)和 NE(東北)。但是并非每一個(gè)位置都有8 個(gè)相鄰位置。如果i,j位于邊界上,即 i=1 ,或 i=m,或 j=1 ,或 j=n ,則相鄰位置可能是3 個(gè).或 5 個(gè)為了避免檢查邊界條件, 將數(shù)組四周圍用值為 1 的邊框包圍起來, 這樣二維數(shù)組 maze 應(yīng)該聲明為 mazem+2,n+2 在迷宮行進(jìn)時(shí),可能有多個(gè)行進(jìn)方向可選,我們可以規(guī)定方向搜索的次序是從東( E)沿順時(shí)針方向進(jìn)行。為了簡(jiǎn)化問題,規(guī)定 i,j的下一步位置的坐標(biāo)是 x,y,并將這 8 個(gè)方位傷的 x 和 y坐標(biāo)的

12、增量預(yù)先放在一個(gè)結(jié)構(gòu)數(shù)組move8 中(見圖 8)。該數(shù)組的每個(gè)分量有兩個(gè)域 dx 和 dy。例如 要向東走,只要在j 值上加上 dy,就可以得到下一步位置的 x,y值為 i,j+dy。于是搜索方向的變化只要令方向值dir 從 0 增至 7,便可以從 move數(shù)組中得到從 i,j點(diǎn)出發(fā)搜索到的每一個(gè)相鄰點(diǎn)x,y。x=i+movedir.dxy=j+movedir.dy圖 7 方向位移圖圖 8 向量差圖為了防止重走原路, 我們規(guī)定對(duì)已經(jīng)走過的位置,將原值為 0 改為 -1 ,這既可以區(qū)別該位置是否已經(jīng)走到過,又可以與邊界值1 相區(qū)別。當(dāng)整個(gè)搜索過程結(jié)束后可以將所有的 -1 改回到 0,從而恢復(fù)迷

13、宮原樣。這樣計(jì)算機(jī)走迷宮的方法是:采取一步一步試探的方法。每一步都從(E).開始,按順時(shí)針對(duì)8 個(gè)方向進(jìn)行探測(cè),若某個(gè)方位上的mazex,y=0,表示可以通行,則走一步;若mazex,y=1,表示此方向不可通行須換方向再試。直至 8 個(gè)方向都試過, mazex,y 均為 1,說明此步已無路可走,需退回一步,在上一步的下一個(gè)方向重新開始探測(cè)。 為此需要設(shè)置一個(gè)棧, 用來記錄所走過的位置和方向( i ,j ,dir )。當(dāng)退回一步時(shí), 就從棧中退出一個(gè)元素, 以便在上一個(gè)位置的下一個(gè)方向上探測(cè),如又找到一個(gè)行進(jìn)方向, 則把當(dāng)前位置和新的方向重新進(jìn)棧, 并走到新的位置。如果探測(cè)到 x=m, y=n,

14、則已經(jīng)到達(dá)迷宮的出口,可以停止檢測(cè),輸出存在棧中的路徑;若在某一位置的 8 個(gè)方向上都堵塞,則退回一步,繼續(xù)探測(cè),如果已經(jīng)退到迷宮的入口(棧中無元素) ,則表示此迷宮無路徑可通行。2 系統(tǒng)算法(偽代碼描述) :(1) 建立迷宮節(jié)點(diǎn)的結(jié)構(gòu)類型 stack 。(2) 入迷宮圖形 0 表示可以通 1 表示不可以通。 用二維數(shù)組mazem+2n+2 進(jìn)行存儲(chǔ)。數(shù)組四周用 1 表示墻壁,其中入口點(diǎn)(1,1)與出口點(diǎn)( m, n)固定。(3) 函數(shù) path() 對(duì)迷宮進(jìn)行處理,從入口開始:While(!(s->top=-1)&&(dir>=7)|(x=M)&&

15、(y=N)&&(mazexy=-1)For(掃描八個(gè)可以走的方向).If(找到一個(gè)可以走的方向 )進(jìn)入棧標(biāo)志在當(dāng)前點(diǎn)可以找到一個(gè)可以走的方向避免重復(fù)選擇 mazexy=-1不再對(duì)當(dāng)前節(jié)點(diǎn)掃描If(八個(gè)方向已經(jīng)被全部掃描過,無可以通的路)標(biāo)志當(dāng)前節(jié)點(diǎn)沒有往前的路后退一個(gè)節(jié)點(diǎn)搜索If( 找到了目的地 )輸出路徑退出循環(huán)未找到路徑(4) 輸出從入口點(diǎn)到出口點(diǎn)的一條路徑。(5) 輸出標(biāo)有通路的迷宮圖。3. 算法流程圖:.開始初始化迷宮,顯示迷宮初始化方向位移數(shù)組尋找迷宮中的一條出路dir>=7 或??誛hile 棧不空且 dir<7do設(shè) 1,1 為出口FFIf mazex

16、y=0elseIfTT該點(diǎn)數(shù)據(jù)入棧dir+回退一步出口或入口顯示通路結(jié)束圖 9 算法流程圖4. 程序代碼:#define M2 12 /*M2*N2為實(shí)際使用迷宮數(shù)組的大小*/#define N2 11#define maxlen M2 /棧長(zhǎng)度#include <stdio.h>#include<iostream.h>.#include <malloc.h>int M=M2-2,N=N2-2;/M*N迷宮的大小typedef struct /定義棧元素的類型int x,y,dir;elemtype;typedef struct /定義順序棧elemtype

17、 stack maxlen;int top;sqstktp;struct moved/定義方向位移數(shù)組的元素類型對(duì)于存儲(chǔ)坐標(biāo)增量的方向位移數(shù)組move int dx,dy;/void inimaze(int mazeN2)/初始化迷宮int i,j,num;for(i=0,j=0;i<=M+1;i+)/設(shè)置迷宮邊界mazeij=1;for(i=0,j=0;j<=N+1;j+)mazeij=1;for(i=M+1,j=0;j<=N+1;j+)mazeij=1;cout<<"原始迷宮為:"<<endl;for(i=1;i<=M;i

18、+)for (j=1;j<=N;j+)num=(800*(i+j)+1500) % 327;/根據(jù) MN的值產(chǎn)生迷宮if (num<150)&&(i!=M|j!=N)mazeij=1;elsemazeij=0;cout<<mazeij<<" "/顯示迷宮cout<<endl;cout<<endl;/inimaze/void inimove(struct moved move)/初始化方向位移數(shù)組./依次為 East , Southeast ,south ,southwest , west ,nort

19、hwest , north , northeast move0.dx=0;move0.dy=1;move1.dx=1;move1.dy=1;move2.dx=1;move2.dy=0;move3.dx=1;move3.dy=-1;move4.dx=0;move4.dy=-1;move5.dx=-1;move5.dy-=1;move6.dx=-1;move6.dy=0;move7.dx=-1;move7.dy=1;/void inistack(sqstktp *s)/*初始化棧 */s->top=-1;/*inistack*/int push(sqstktp*s,elemtype x)if

20、(s->top=maxlen-1)return(false);elses->stack+s->top=x;/*棧不滿,執(zhí)行入棧操作*/return(true);/*push*/elemtype pop(sqstktp *s)/*棧頂元素出棧*/elemtype elem;if(s->top<0)/如果???,返回空值elem.x=NULL;elem.y=NULL;elem.dir=NULL;return(elem);elses->top-;return(s->stacks->top+1);/棧不空,返回棧頂元素 /pop/void path(int

21、 mazeN2,struct moved move,sqstktp *s)/尋找迷宮中的一條通路.int i,j,dir,x,y,f;elemtype elem;i=1;j=1;dir=0;maze11=-1;/設(shè) 11為入口處dox=i+movedir.dx;/球下一步可行的到達(dá)點(diǎn)的坐標(biāo)y=j+movedir.dy;if(mazexy=0)elem.x=i;elem.y=j;elem.dir=dir;f=push(s,elem);/如果可行將數(shù)據(jù)入棧if(f=false)/如果返回假,說明棧容量不足cout<<" 棧長(zhǎng)不足 "i=x;j=y;dir=0;maz

22、exy=-1;elseif (dir < 7)dir+;elseelem=pop(s);/8個(gè)方向都不行,回退if(elem.x!=NULL)i=elem.x;j=elem.y;dir=elem.dir+1;while(!(s->top=-1)&&(dir>=7)|(x=M)&&(y=N)&&(mazexy=-1);/循環(huán)if(s->top=-1)/若是入口,則無通路cout<<" 此迷宮不通 "elseelem.x=x; elem.y=y; elem.dir=dir;/將出口坐標(biāo)入棧f=push(s,elem);cout<<" 迷宮通路是: "<<endl;i=0;while (i <= s->top)cout<<"("<<s->stacki.x<<","<<s->stacki.y<<")"/顯示迷宮通路if(i!=s->top).cout<<"->"

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論