Maze迷宫问题(求最优解)

迷宫地形我们可以通过读文件的形式,通过已知入口逐个遍历坐标寻找通路。

文件如图:

wKiom1cSCnTB8pO4AAAZiAM5LuE146.png

每个坐标的位置用结构体来记录:

struct Pos    //位置坐标
{
   int  _row;
   int _col;
};

 定义行列范围:

#define M 10   //行
#define N 10   //列

初始化迷宫数组
将通过读文件的方式获取的字符转成整型数据,保存在M行N列的数组中。

void InitMaze(int* maze)
{  
    struct WavHeadhWAV;
    FILE* fout = fopen("MazeMap.txt", "r");   // .txt文件要放在当前目录下
    if (fout == NULL)                       // 这里一定要检查读文件是否成功
    {
        cout << "can't find MazeMap.txt !" << endl<<endl;
        return;
    }
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N;)
        {
            char ch = fgetc(fout);
            if (ch=='1'||ch=='0')
            {
                maze[i*N + j] = ch - '0';
                j++;
            }
        }
    }
    fclose(fout);
}

回溯查找通路

利用栈来存储通路,通过上下左右四个方向依次遍历,如果该位置满足条件,就将它入栈,并将该位置的数据置为2;如果四个方向都不满足条件就执行出栈操作,回溯查找满足条件的位置(这时候如果栈为空了,说明查找通路失败),继续循环遍历,直到找到出口为止。

这里建立一个最小栈,如果找到出路,就将该栈赋给最小栈,并将出口置为1,继续回溯查找通路,如果又一次找到通路,就将该栈的长度与最小栈进行比较,如果该栈长度比最小栈还要小,就将它再一次赋给最小栈(保证最小栈是最短的通路),继续回溯,直到整个栈为空,回到了入口,程序结束。

bool SearchMazePath(int *maze, Pos entry, stack<Pos>& paths)   // 利用栈回溯查找通路,并实现迷宫的最优解
{
    assert(maze);
    stack<Pos>min;
    paths.push(entry);
    while (!paths.empty())
    {
        Pos cur = paths.top();
        maze[cur._row*N+cur._col] = 2;
        if (cur._row==M-1)
        {
            if (paths.size()< min.size() || min.size() == 0)
            {
                min = paths;
            }
            paths.pop();
            maze[min.top()._row*N + min.top()._col] = 1;
        }  
        Pos next = cur;
        next._col--;  //左
        if (CheckIsAccess(maze, next))
        {
            paths.push(next);
            maze[next._row*N + next._col] = 2;
            continue;
        }
        next = cur;
        next._col++; //右
        if (CheckIsAccess(maze, next))
        {
            paths.push(next);
            maze[next._row*N + next._col] = 2;
            continue;
        }
        next = cur;
        next._row--; //上
        if (CheckIsAccess(maze, next))
        {
            paths.push(next);
            maze[next._row*N + next._col] = 2;
            continue;
        }
        next = cur;
        next._row++; //下
        if (CheckIsAccess(maze, next))
        {
            paths.push(next);
            maze[next._row*N + next._col] = 2;
            continue;
        }
        paths.pop();
    }
    if (paths.empty()&&!min.empty())
    {
            maze[min.top()._row*N + min.top()._col] = 2;
            return true;
    }
    return false;
}

  检查该位置是否合法:(坐标在行列范围之内)

bool CheckIsAccess(int* maze, const Pos& next)    // 检查该位置是否合法
{
    assert(maze);
    if ((next._row >= 0 && next._row <= N) && (next._col >= 0 && next._col < M) && maze[next._row*N + next._col] == 0)
    {
        return true;
    }
    return false;
}

  打印迷宫:

void PrintMaze(int *maze)   // 打印迷宫
{
    assert(maze);
    for (int i = 0; i < M; i++)
    { 
        for (int j = 0; j < N; j++)
        {
            cout << maze[i*N + j] <<" " ;
        }
        cout << endl;
    }
    cout << endl;  
}

  

 

posted @ 2016-04-18 16:04  ProLyn  阅读(1547)  评论(0编辑  收藏  举报