迷宫最短路径问题解析

有一个二维数组,0表示路,-1表示墙,求其中任意两点的最短路径。

我们先看,怎么求一条路径:求两点路径是一个数据结构上的典型的迷宫问题,很多数据结构的书上都有介绍,解决办法如下:

从一点开始出发,向四个方向查找,每走一步,把走过的点的值+1(即本节点值+1),防止重复行走,并把走过的点压入堆栈(表示路径),如果遇到墙、或者已走过的点则不能前进,如果前方已经无路可走,则返回,路径退栈,这样递归调用,直到找到终点为止。

迷宫如下图所示:

《迷宫最短路径问题解析》

从(2, 1)到(6, 8),程序如下所示:

 

《迷宫最短路径问题解析》
struct Postion
《迷宫最短路径问题解析》

{
《迷宫最短路径问题解析》    
int _X, _Y;
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》    Postion()
{}
《迷宫最短路径问题解析》    Postion(
int X, int Y)
《迷宫最短路径问题解析》        : _X(X), _Y(Y)
{}
《迷宫最短路径问题解析》}

;
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》bool isCanGo(const 

int
 prePosValue,
《迷宫最短路径问题解析》             const 

int
 posX,
《迷宫最短路径问题解析》             const 

int
 posY)
《迷宫最短路径问题解析》

{
《迷宫最短路径问题解析》    
if (   posX < 0 || posX > 9        // 越界
《迷宫最短路径问题解析》
        || posY < 0 || posY > 9        
《迷宫最短路径问题解析》        
|| maze[posX][posY] == 1    // 墙
《迷宫最短路径问题解析》
        || maze[posX][posY] >= 1)    // 走过
《迷宫最短路径问题解析》
    {
《迷宫最短路径问题解析》        
return false;
《迷宫最短路径问题解析》    }

《迷宫最短路径问题解析》
《迷宫最短路径问题解析》    
return true;
《迷宫最短路径问题解析》}


《迷宫最短路径问题解析》
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》stack

<
Postion
>
 path__;            
//
路径

《迷宫最短路径问题解析》

        
《迷宫最短路径问题解析》Postion offset[

4
];                
//
路径

《迷宫最短路径问题解析》


《迷宫最短路径问题解析》bool shortestPath(stack

<
Postion
>
 
&
path,
《迷宫最短路径问题解析》                  const Postion 

&
start,
《迷宫最短路径问题解析》                  const Postion 

&
end)
《迷宫最短路径问题解析》

{
《迷宫最短路径问题解析》    
if (   start._X == end._X 
《迷宫最短路径问题解析》        
&& start._Y == end._Y)
《迷宫最短路径问题解析》    
{
《迷宫最短路径问题解析》        path__ 
= path;
《迷宫最短路径问题解析》        
return true;
《迷宫最短路径问题解析》    }

《迷宫最短路径问题解析》    
《迷宫最短路径问题解析》    
for (int i = 0; i < 4; i++)
《迷宫最短路径问题解析》    
{
《迷宫最短路径问题解析》        
int nNextPos_X = start._X + offset[i]._X;
《迷宫最短路径问题解析》        
int nNextPos_Y = start._Y + offset[i]._Y;
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》        
if (isCanGo(maze[start._X][start._Y], nNextPos_X, nNextPos_Y))
《迷宫最短路径问题解析》        
{
《迷宫最短路径问题解析》            maze[nNextPos_X][nNextPos_Y] 
= maze[start._X][start._Y] + 1;
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》            path.push(Postion(nNextPos_X, nNextPos_Y));
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》            
if (shortestPath(path, Postion(nNextPos_X, nNextPos_Y), end))
《迷宫最短路径问题解析》                
return true;
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》            path.pop();
《迷宫最短路径问题解析》        }

《迷宫最短路径问题解析》    }

《迷宫最短路径问题解析》
《迷宫最短路径问题解析》    
return false;
《迷宫最短路径问题解析》}


《迷宫最短路径问题解析》
《迷宫最短路径问题解析》

int
 main(
int
 argc, 
char
*
 argv[])
《迷宫最短路径问题解析》

{
《迷宫最短路径问题解析》    offset[
0]._X = 1;    offset[0]._Y = 0;    // 上
《迷宫最短路径问题解析》
    offset[1]._X = 1;    offset[1]._Y = 0;    // 下
《迷宫最短路径问题解析》
    offset[2]._X = 0;    offset[2]._Y = 1;    // 左
《迷宫最短路径问题解析》
    offset[3]._X = 0;    offset[3]._Y = 1;    // 右
《迷宫最短路径问题解析》

《迷宫最短路径问题解析》    printMat(maze);
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》    Postion start(
21), end(68);
《迷宫最短路径问题解析》    maze[start._X][start._Y] 
= 1;            // 置起点值1, 防止走回起点
《迷宫最短路径问题解析》
    shortestPath(stack<Postion>(), start, end);
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》    printPath(path__);
《迷宫最短路径问题解析》    printMat(maze);
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》    
return 0;
《迷宫最短路径问题解析》}


《迷宫最短路径问题解析》

这时,我们经过运算,到达终点,有44步之多。如果我们调整调用offset的顺序,即先左右,后上下,可能会得到更短的路径,但无法确保在任何情况下都能得到最短路径。

得到最短路径的方法,解决方法如下:

每走一步,就对前方的节点赋值为此节点+1,走过的路径也可以重复行走。但有一个条件,就是本节点+1必须小于已走过的节点的权值(墙不能走),这样走遍所有的节点,记录最短的路径。

主要修改了以下两个函数:

《迷宫最短路径问题解析》
bool isCanGo(const 
int
 prePosValue,
《迷宫最短路径问题解析》             const 

int
 posX,
《迷宫最短路径问题解析》             const 

int
 posY)
《迷宫最短路径问题解析》

{
《迷宫最短路径问题解析》    
if (   posX < 0 || posX > 9        // 越界
《迷宫最短路径问题解析》
        || posY < 0 || posY > 9        
《迷宫最短路径问题解析》        
|| maze[posX][posY] == 1)    // 墙
《迷宫最短路径问题解析》
    {
《迷宫最短路径问题解析》        
return false;
《迷宫最短路径问题解析》    }

《迷宫最短路径问题解析》
《迷宫最短路径问题解析》    
if (maze[posX][posY] == 0)    // 未走过
《迷宫最短路径问题解析》
        return true;
《迷宫最短路径问题解析》    
else                        // 更近的路径
《迷宫最短路径问题解析》
        return (prePosValue + 1< maze[posX][posY];
《迷宫最短路径问题解析》}


《迷宫最短路径问题解析》
《迷宫最短路径问题解析》

void
 shortestPath(stack
<
Postion
>
 
&
path,
《迷宫最短路径问题解析》                  const Postion 

&
start,
《迷宫最短路径问题解析》                  const Postion 

&
end)
《迷宫最短路径问题解析》

{
《迷宫最短路径问题解析》    
if (   start._X == end._X 
《迷宫最短路径问题解析》        
&& start._Y == end._Y)
《迷宫最短路径问题解析》    
{
《迷宫最短路径问题解析》        
if (path.size() < path__.size() || path__.empty())    // 更短的路径
《迷宫最短路径问题解析》
            path__ = path;
《迷宫最短路径问题解析》        
return;
《迷宫最短路径问题解析》    }

《迷宫最短路径问题解析》    
《迷宫最短路径问题解析》    
for (int i = 0; i < 4; i++)
《迷宫最短路径问题解析》    
{
《迷宫最短路径问题解析》        
int nNextPos_X = start._X + offset[i]._X;
《迷宫最短路径问题解析》        
int nNextPos_Y = start._Y + offset[i]._Y;
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》        
if (isCanGo(maze[start._X][start._Y], nNextPos_X, nNextPos_Y))
《迷宫最短路径问题解析》        
{
《迷宫最短路径问题解析》            maze[nNextPos_X][nNextPos_Y] 
= maze[start._X][start._Y] + 1;
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》            path.push(Postion(nNextPos_X, nNextPos_Y));
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》            shortestPath(path, Postion(nNextPos_X, nNextPos_Y), end);
《迷宫最短路径问题解析》
《迷宫最短路径问题解析》            path.pop();
《迷宫最短路径问题解析》        }

《迷宫最短路径问题解析》    }

《迷宫最短路径问题解析》}


《迷宫最短路径问题解析》 

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/a1259109679/article/details/48084951
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞