迷宫最短路径c ++

时间:2016-01-30 23:20:38

标签: c++ breadth-first-search depth-first-search maze

我需要计算从一个起点到另一个终点的距离和路径。 http://coliru.stacked-crooked.com/a/b15078829f49df3c

int pathExists(char maze[][10], int sr, int sc, int er, int ec, int distance, int direction) {

    /*if(maze[sr][sc] != '.') . es visitable, x pared
        return 0;
 */
 int lmin=99, l;
    if(maze[sr][sc] != '.') //You cannot visit it, or is wall or is @ visited
        return 0;

    if(sr == er  &&  sc == ec) {
        display(maze); 
        cout << "Distance to end point is:  " << distance << endl; 
        //if ( lmin==l) PathBueno = PathInt;
        for (int i = 0; i < PathInt.size(); i++) {
            cout << PathInt[i];
            }
        return distance;
    }
    /*
    if(distance == 15) {
        cout << "Cant make it in 15 steps" << endl;
        return 0;
    }
    */
   // path.push_back(vertex);
    //Path.append(direction);
    PathInt.push_back(direction);
    maze[sr][sc] = '@';  // anything non-'.' will do



    //Row --  Norte
    l = pathExists(maze, sr - 1, sc, er, ec, distance + 1,1);
    if(l > 0 && l<lmin) {
        lmin = l; 
       // Path.append("N");
    }
    //Row ++  Sur
    l = pathExists(maze, sr + 1, sc, er, ec, distance + 1,2);
    if(l > 0 && l<lmin) {
        lmin = l; 
        //Path.append("S");
    }

    //Column --  Oeste
    l = pathExists(maze, sr, sc - 1, er, ec, distance + 1,3);
    if(l > 0 && l<lmin) 
        {
        lmin = l; 
        //Path.append("W");
    }

    //Column ++  Este
    l = pathExists(maze, sr, sc + 1, er, ec, distance + 1,4);
    if(l > 0 && l<lmin) 
    {
        lmin = l; 
        //Path.append("E");
    }

    maze[sr][sc] = '.'; //restore
    PathInt.pop_back();
    //if ( Path.size() > 2) Path.erase(Path.size() - 1);

    return lmin;
}

我一直在尝试很多东西。但是我不能在PathGood中打印或保存从一个点到另一个点的最短路径。 在示例中,我想从8.4移动到8.1 ...所以最短路径有3步距离,路径是EEE或333(假设3是EAST)。

可验证的例子:

int main() {
    char maze[10][10] = {
        {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'},
        {'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
        {'X', '.', 'X', 'X', 'X', 'X', '.', 'X', 'X', 'X'},
        {'X', '.', '.', 'X', '.', 'X', '.', '.', '.', 'X'},
        {'X', '.', '.', 'X', '.', '.', '.', 'X', '.', 'X'},
        {'X', '.', 'X', 'X', '.', 'X', 'X', 'X', '.', 'X'},
        {'X', '.', 'X', '.', '.', '.', '.', 'X', 'X', 'X'},
        {'X', '.', '.', 'X', 'X', '.', 'X', 'X', '.', 'X'},
        {'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
        {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}
    };

    Path.clear();

    int  slen = pathExists(maze,8,4, 8, 1,0,0); 




    if(slen) {
        cout << "Solvable in "<<slen<<" steps !" << endl;
    //  cout << "Complete path is : " << Path;
    //    std::cout << "Complete path is : " << PathGood;
    }
    else
        cout << "Out of luck!" << endl;
    cin.get();

    //int len, i;
  /*  len = (int)strlen(string);
        for (int i = 0; i < PathBueno.size(); i++) {
            cout << PathBueno[i];
            }*/
}

我试图在pacman游戏中给一些IA给鬼。所以我需要知道步骤中的最短距离(避开墙壁)然后开始移动。

任何帮助将不胜感激......

顺便说一下,我正在尝试使用DFS,我认为BFS会更有效率,所以如果有人可以帮助将它转换为BFS ..(BFS比DFS更好)

现在我知道什么是更好的解决方案,但我不知道要采取哪个方向,因为程序可以存储最佳路径。

PS:

我开始尝试使用字符串并附加字符和“N”,“W”,“S”等等...

2 个答案:

答案 0 :(得分:0)

问题是您没有存储最短路径(PathMin?)。

解决此问题的方法不止一种。在您的代码中,pathExists返回int,这是最短路径的长度。相反,它可以返回vector<int>这是最短的路径。

我认为BFS比DFS更适合这项任务;将此代码转换为BFS将很困难。我建议你保持一个位置矢量,就像一队搜索者从起点向外穿过迷宫。搜索者轮流移动;当一个搜索者可以进行多次移动时,它会分成多个搜索者;当一个搜索者不动,它就会死去;当搜索者到达目的地时,搜索结束。

答案 1 :(得分:0)

感谢@Beta,但经过大量测试后,我发现这个结果非常完美:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <map>

using namespace std;
//using String = char *;

std::string Path;
std::string PathGood;
vector<int> PathInt;
vector<int> PathBueno;
std::map < int, vector<int>> lista; 

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
    out << "[";
    size_t last = v.size() - 1;
    for(size_t i = 0; i < v.size(); ++i) {
        out << v[i];
        if (i != last) 
            out << ", ";
    }
    out << "]";
    return out;
}

/*std::map<char,int> mymap;

  // first insert function version (single parameter):
  mymap.insert ( std::pair<char,int>('a',100) );
  mymap.insert ( std::pair<char,int>('z',200) );

  ret = mymap.insert ( std::pair<char,int>('z',500) );
  if (ret.second==false) {
    std::cout << "element 'z' already existed";
    std::cout << " with a value of " << ret.first->second << '\n';
  }
 */
void display(char maze[][10]) {
    for(int i = 0; i < 10; i++) {
        copy(maze[i], maze[i] + 10, ostream_iterator<char>(cout, ""));
        cout << endl;
    }
}


int pathExists(char maze[][10], int sr, int sc, int er, int ec, int distance, int direction) {

    /*if(maze[sr][sc] != '.') . es visitable, x pared
        return 0;
 */
 int lmin=99, l;
    if(maze[sr][sc] != '.') //You cannot visit it, or is wall or is @ visited
        return 0;

    if(sr == er  &&  sc == ec) {
        display(maze); 
        cout << "Distance to end point is:  " << distance << endl;
        cout << "Ultima direccion ess:  " << direction << endl; 
        //if ( lmin==l) PathBueno = PathInt;
        PathInt.push_back(direction);
        lista.insert ( std::pair<int,vector<int>>(distance,PathInt));
        PathInt.pop_back();
        return distance;
    }
    /*
    if(distance == 15) {
        cout << "Cant make it in 15 steps" << endl;
        return 0;
    }
    */
   // path.push_back(vertex);
    //Path.append(direction);
    PathInt.push_back(direction);
    maze[sr][sc] = '@';  // anything non-'.' will do



    //Row --  Norte
    l = pathExists(maze, sr - 1, sc, er, ec, distance + 1,1);
    if(l > 0 && l<lmin) {
        lmin = l; 
       // Path.append("N");
    }
    //Row ++  Sur
    l = pathExists(maze, sr + 1, sc, er, ec, distance + 1,2);
    if(l > 0 && l<lmin) {
        lmin = l; 
        //Path.append("S");
    }

    //Column --  Oeste
    l = pathExists(maze, sr, sc - 1, er, ec, distance + 1,3);
    if(l > 0 && l<lmin) 
        {
        lmin = l; 
        //Path.append("W");
    }

    //Column ++  Este
    l = pathExists(maze, sr, sc + 1, er, ec, distance + 1,4);
    if(l > 0 && l<lmin) 
    {
        lmin = l; 
        //Path.append("E");
    }

    maze[sr][sc] = '.'; //restore
    PathInt.pop_back();
    //if ( Path.size() > 2) Path.erase(Path.size() - 1);

    return lmin;
}



int main() {
    char maze[10][10] = {
        {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'},
        {'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
        {'X', '.', 'X', 'X', 'X', 'X', '.', 'X', 'X', 'X'},
        {'X', '.', '.', 'X', '.', 'X', '.', '.', '.', 'X'},
        {'X', '.', '.', 'X', '.', '.', '.', 'X', '.', 'X'},
        {'X', '.', 'X', 'X', '.', 'X', 'X', 'X', '.', 'X'},
        {'X', '.', 'X', '.', '.', '.', '.', 'X', 'X', 'X'},
        {'X', '.', '.', 'X', 'X', '.', 'X', 'X', '.', 'X'},
        {'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
        {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}
    };

    Path.clear();

    int  slen = pathExists(maze,5,4, 3, 1,0,0); 




    if(slen) {
        cout << "Solvable in "<<slen<<" steps !" << endl;
    //  cout << "Complete path is : " << Path;
    //    std::cout << "Complete path is : " << PathGood;
    }
    else
        cout << "Out of luck!" << endl;
    cin.get();

    // showing contents:
  std::map<int,std::vector<int>>::iterator it = lista.begin();
  std::cout << "Mi lista contains:\n";
  for (it=lista.begin(); it!=lista.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  int direccionb = lista.find(slen)->second[1];

  cout << "La direccion buena de la buena es :" << direccionb << endl;

}