生活随笔
收集整理的這篇文章主要介紹了
回溯法解迷宫问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? 迷宮問題中,在尋找路徑時,采用的方法通常是:從入口出發,沿某一方向向前試探,若能走通,則繼續向前進;如果走不通,則要沿原路返回,換一個方向再繼續試探,直到所有可能的能跟都試探完成為止。為了保證在任何位置上都能沿原路返回(回溯),要建立一個后進先出的棧來保存從入口到當前位置的路徑。
????? 而且在求解迷宮路徑中,所求得的路徑必須是簡單路徑。即在求得的路徑上不能有重復的同一塊通道。
????? 為了表示迷宮,設置一個數組,其中每個元素表示一個方塊的狀態,為0時表示對應方塊是通道,為1時表示對應方塊為墻,數組如下所示:
[cpp]?view plaincopy
int?mg[10][10]?=?{???????? ????{1,1,1,1,1,1,1,1,1,1},?? ????{1,0,0,1,1,0,0,1,0,1},?? ????{1,0,0,1,0,0,0,1,0,1},?? ????{1,0,0,0,0,1,1,0,0,1},?? ????{1,0,1,1,1,0,0,0,0,1},?? ????{1,0,0,0,1,0,0,0,0,1},?? ????{1,0,1,0,0,0,1,0,0,1},?? ????{1,0,1,1,1,0,1,1,0,1},?? ????{1,1,0,0,0,0,0,0,0,1},?? ????{1,1,1,1,1,1,1,1,1,1}};??
????? 對于迷宮中每個方塊,都有上下左右四個方塊相鄰,第i行第j列的當前方塊的位置為(i,j),規定上方方塊為方位0,按順時針方向遞增編號。假設從方位0到方位3的方向查找下一個可走方塊。
????? 為便于回溯,對于可走的方塊都要進棧,并試探它的下一個可走方位,將這個可走的方位保存到棧中,棧定義如下:
[cpp]?view plaincopy
struct?St?????????????????? {?? ????int?i;????????????????? ????int?j;????????????????? ????int?di;???????????????? }?St[MaxSize];?????????????
????? 求解路徑過程為:先將入口進棧(初始方位設置為-1),在棧不為空時循環:取棧頂方塊(不退棧),若是出口,則輸出棧中方塊即為路徑。否則,找下一個可走的相鄰方塊,若不存在這樣的方塊,則退棧。若存在,即將其方位保存到棧頂元素中,并將這個可走相鄰方塊進棧(初始方位設置為-1)。
????? 為保證試探可走相鄰方塊不是已走路徑上的方塊,如(i,j)已經進棧,在試探(i+1,j)的下一可走方塊時,又試探到(i,j),這樣會引起死循環,為此,在一個方塊進棧后,將對應的mg數組元素值改為-1(變為不可走),當退棧時(沒有可走的相鄰方塊),將其恢復為0.
????? 算法如下:
[cpp]?view plaincopy
#include?<iostream>???????? #include?<iomanip>???? #include?<stdlib.h>?? using?namespace?std;??? ?? ?? #define?MaxSize?100?? ?? int?mg[10][10]?=?{???????? ????{1,1,1,1,1,1,1,1,1,1},?? ????{1,0,0,1,1,0,0,1,0,1},?? ????{1,0,0,1,0,0,0,1,0,1},?? ????{1,0,0,0,0,1,1,0,0,1},?? ????{1,0,1,1,1,0,0,0,0,1},?? ????{1,0,0,0,1,0,0,0,0,1},?? ????{1,0,1,0,0,0,1,0,0,1},?? ????{1,0,1,1,1,0,1,1,0,1},?? ????{1,1,0,0,0,0,0,0,0,1},?? ????{1,1,1,1,1,1,1,1,1,1}};?? ?? struct?St?????????????????? {?? ????int?i;????????????????? ????int?j;????????????????? ????int?di;???????????????? }?St[MaxSize];????????????? ?? int?top?=?-1;?????????????? ?? void?MgPath(int?xi,?int?yi,?int?xe,?int?ye)?????????????? {?? ????int?i,?j,?di,?find,?k;?? ????top++;??????????????????????????????????????????????? ????St[top].i?=?xi;St[top].j?=?yi;St[top].di?=?-1;?? ????mg[xi][yi]?=?-1;?? ????while(top>-1)???????????????????????????????????????? ????{?? ????????i?=?St[top].i;j?=?St[top].j;di?=?St[top].di;?? ????????if(i==xe?&&?j==ye)??????????????????????????????? ????????{?? ????????????cout?<<?"迷宮路徑如下:/n";?? ????????????for(k=0;?k<=top;?k++)?? ????????????{?? ????????????????cout?<<?"/t("?<<?St[k].i?<<?","?<<?St[k].j?<<?")";?? ????????????????if((k+1)%5==0)?cout?<<?endl;?????????????? ????????????}?? ????????????cout?<<?endl;?? ????????????return;?? ????????}?? ????????find?=?0;?? ????????while(di<4?&&?find==0)???????????????????????????? ????????{?? ????????????di++;?? ????????????switch(di)?? ????????????{?? ????????????case?0:i?=?St[top].i-1;?j?=?St[top].j;?break;?? ????????????case?1:i?=?St[top].i;?j?=?St[top].j+1;?break;?? ????????????case?2:i?=?St[top].i+1;?j?=?St[top].j;?break;?? ????????????case?3:i?=?St[top].i;?j?=?St[top].j-1;?break;?? ????????????}?? ????????????if(mg[i][j]==0)?find?=?1;???????????????????????? ????????}?? ????????if(find==1)?????????????????????????????????????????? ????????{?? ????????????St[top].di?=?di;????????????????????????????????? ????????????top++;??????????????????????????????????????????? ????????????St[top].i?=?i;?St[top].j?=?j;?St[top].di?=?-1;?? ????????????mg[i][j]?=?-1;??????????????????????????????????? ????????}?? ????????else????????????????????????????????????????????????? ????????{?? ????????????mg[St[top].i][St[top].j]?=?0;???????????????????? ????????????top--;?? ????????}?? ????}?? ????cout?<<?"沒有可走路徑!/n";?? }?? ?? int?main()?? {?? ????MgPath(1,1,8,8);?? }??
總結
以上是生活随笔為你收集整理的回溯法解迷宫问题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。