有一个二维数组,0表示路,-1表示墙,求其中任意两点的最短路径。
我们先看,怎么求一条路径:求两点路径是一个数据结构上的典型的迷宫问题,很多数据结构的书上都有介绍,解决办法如下:
从一点开始出发,向四个方向查找,每走一步,把走过的点的值+1(即本节点值+1),防止重复行走,并把走过的点压入堆栈(表示路径),如果遇到墙、或者已走过的点则不能前进,如果前方已经无路可走,则返回,路径退栈,这样递归调用,直到找到终点为止。
迷宫如下图所示:
从(2, 1)到(6, 8),程序如下所示:
struct Postion
{
int_X, _Y;
Postion(){} Postion(intX,intY)
: _X(X), _Y(Y){}};
bool isCanGo(constintprePosValue,
constintposX,
constintposY)
{
if( posX<0||posX>9//越界||posY<0||posY>9||maze[posX][posY]==-1//墙||maze[posX][posY]>=1)//走过
{
returnfalse;
}
returntrue;
}
stackpath__;//路径Postion offset[4];//路径bool shortestPath(stack&path,
const Postion&start,
const Postion&end)
{
if( start._X==end._X
&&start._Y==end._Y)
{
path__=path;
returntrue;
}
for(inti=0; i<4; i++)
{
intnNextPos_X=start._X+offset[i]._X;
intnNextPos_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))
returntrue;
path.pop();
} }
returnfalse;
}
intmain(intargc,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(2,1), end(6,8);
maze[start._X][start._Y]=1;//置起点值1, 防止走回起点shortestPath(stack(), start, end);
printPath(path__);
printMat(maze);
return0;
}
这时,我们经过运算,到达终点,有44步之多。如果我们调整调用offset的顺序,即先左右,后上下,可能会得到更短的路径,但无法确保在任何情况下都能得到最短路径。
得到最短路径的方法,解决方法如下:
每走一步,就对前方的节点赋值为此节点+1,走过的路径也可以重复行走。但有一个条件,就是本节点+1必须小于已走过的节点的权值(墙不能走),这样走遍所有的节点,记录最短的路径。
主要修改了以下两个函数:
bool isCanGo(constintprePosValue,
constintposX,
constintposY)
{
if( posX<0||posX>9//越界||posY<0||posY>9||maze[posX][posY]==-1)//墙
{
returnfalse;
}
if(maze[posX][posY]==0)//未走过returntrue;
else//更近的路径return(prePosValue+1)
}
voidshortestPath(stack&path,
const Postion&start,
const Postion&end)
{
if( start._X==end._X
&&start._Y==end._Y)
{
if(path.size()path__=path;
return;
}
for(inti=0; i<4; i++)
{
intnNextPos_X=start._X+offset[i]._X;
intnNextPos_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();
} }}
我上传了两个工程,求一条路径的程序点此下载,求最短路径的程序点此下载。
文章结束!愿它对您有所帮助。
posted on 2008-03-18 17:47 胡满超 阅读(8185) 评论(4) 编辑 收藏 引用