迷宫算法

 

 

迷宫算法
算法思想 :findpath 首先创建一个足够大的堆栈,然后对偏移量数组进行初始化,并在迷宫周围增加一圈障碍物。在 while 循环中,从当前位置 here 出发,按下列次序来选择下一个移动位置:向右、向下、向左、向上。如果能够移动到下一个位置,则将当前位置放入堆栈 path ,并移动到下一个位置。如果找不到下一个可移动的位置,则退到前一个位置。如果无法回退一个位置(即堆栈为空),则表明不存在通往出口路径。当回退至堆栈的顶部位置( next )时,可以重新选择另一个可能的相邻位置,这可利用 next here 来推算。注意 here next 的一个邻居。对下一个移动位置选择可用以下代码来实现:
If(next.row==here.row)// 推算 next 可移动位置的个数
Option=2+next.col-here.col;
else option=3+next.row;
 
Struct position{// 位置
int row;//
Int col;//
}position;
 
Status FindPath()
{// 寻找从位置( 1 1 )到出口( m,m )的路径
Position offset[4]
Offset[0].row=0;offset[0].col=1;// 向右
Offset[1].row=1;offset[1].col=0;// 向下
Offset[2].row=0;offset[2].col=-1;// 向左
Offset[3].row=-1;offset[3].col=0;// 向上
// 在迷宫周围增加一圈障碍物
for(int i=0;i<=m+1;i++)
{
maze[0][i]=maze[m+1][i]=1;// 底和顶
maze[i][0]=maze[i][m+1]=1;// 左和右
}
// 优点:是程序不必处理边界条件,简化代码设计。
Path=new Stack<Position>(m*m-1);
Position here;
here.row=1;
here.col=1;
maze[1][1]=1;// 阻止返回入口
int option=3;
while(here.row!=m&&here.col!=m)// 不是出口
{// 寻找并移动到一个相邻位置
int r,c;
while(option<=LastOption)
{
r=here.row+offset[option].row;// 设置相邻格点
c=here.col+offset[option].col;
if(maze[r][c]==0) break;
option++;
}
// 找到一个相邻位置了吗?
if(option<=LastOption)
{// 移动到 maze[r][c]
path->add(here);
here.row=r;
here.col=c;
// 设置障碍以阻止再次访问
maze[r][c]=1;
option=0;
}
else{// 没有可用的相邻位置,回溯
path->isEmpty() return OK;
Position next;
Path->Delete(next);// 退回至栈顶位置 next
If(next.row==here.row)// 推算 next 可移动位置的个数
Option=2+next.col-here.col;
else option=3+next.row;
here=next;
}
return ERROR;
}
最短路径算法
算法思想:程序首先检查 start finish 是否相同,如果相同,则路径长度为 0 ,程序终止。否则设置一堵由封锁位置构成的“围墙”,把网格包围起来。然后对 offset 数组进行初始化,并在起始位置上标记 2 。借助于队列 Q 并从位置 start 开始,直到移动到下 start 相距为 1 的网格位置,然后移动到 start 相距为 2 的网格位置,不断继续下去,直到到达位置 finish 或者无法继续移动到下一个新的、空白的位置。在后一种情况下,将不存在到达位置 finish 的路径,而在前一种情况下,位置 finish 将得到一个相应的编号。
如果到达了 finish ,则可以利用网格上的标号来重构路径。路径上的位置( start 除外)均被存储在数组 path 之中。
 
Status FindPath(Position start,Position finish,int &Pathlen,Position*path)
{// 寻找从 start finish 的路径
if((start.row==finish.row)&&(start.col==finish.col))
{
Pathlen=0;
return OK;
}
Position offset[4]
Offset[0].row=0;offset[0].col=1;// 向右
Offset[1].row=1;offset[1].col=0;// 向下
Offset[2].row=0;offset[2].col=-1;// 向左
Offset[3].row=-1;offset[3].col=0;// 向上
// 在迷宫周围增加一圈障碍物
for(int i=0;i<=m+1;i++)
{
maze[0][i]=maze[m+1][i]=1;// 底和顶
maze[i][0]=maze[i][m+1]=1;// 左和右
}
int NumOfNbr=4;// 一个网络个位置的相邻位置数
Position here,nbr;
here.row=start.row;
here.col=start.col;
Maze[start.row] [start.col]=2;// 封锁初始位置
LinkQueue<Position>Q;
Do
{// 标记相邻位置
for(int i=0;i< NumOfNbr;i++)
{
nbr.row=here.row+offset[option].row;
nbr.col=here.col+offset[option].col; // 设置相邻格点
if(maze[nbr.row][ nbr.col]==0)// 通路,且未被标记
{
maze[nbr.row][ nbr.col]=maze[here.row][ here.col]+1;
if((nbr.row==finish.row)&&( nbr.col==finish.col)) break;// 找到宝藏完成标记
Q.add(nbr);
}//if 结束
}//for 结束
 
// 已到达 finish 吗?
if((nbr.row==finish.row)&&( nbr.col==finish.col)) break;
 
// 未到达 finish, 可移动到 nbr 吗?
If(Q.IsEmpty()) return ERROR;
Q.delete(here);
}while(OK)
 
// 构造路径
PathLen=maze[finish.row][ finish.col]-2;
Path=new Position[Pathlen];
 
// 回溯自 finish
here=finish;
for(int j=pathLen-1;j>=0;j--)
{
path[j]=here;
// 寻找前一个位置
for(int i=0;i< NumOfNbr;i++)
{
nbr.row=here.row+offset[option].row;
nbr.col=here.col+offset[option].col;
if(maze[nbr.row][ nbr.col]==j+2) break;
}
here=nbr;// 移动到前一位置
}
return OK;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值