【问题标题】:Backtracking maze solver in CC中的回溯迷宫求解器
【发布时间】:2015-12-05 07:27:18
【问题描述】:

我正在为迷宫 [30][30] 编写查找路径解决方案 我在路径查找功能中使用了回溯; 这是伪代码:

bool find_path(myMap,myVisited,myPath,v,h)

  1. 找到起点[v,h],然后针对该点运行find_path函数
  2. 将房间标记为已访问
  3. 终止条件1:如果h=29,标记路径然后返回true
  4. 递归部分:搜索8个邻居:west,northwest,north,northeast,east,southeast,south,southwest。 检查房间是否可访问,然后调用 find_path 函数,如果返回 true,则在查找路径上标记。
  5. 终止条件 2:返回 false。

当我运行它时,它总是给出分段错误。我尝试了不同的方法,但都给出了相同的错误? 输出应该是这样的图像: http://postimg.org/image/cd8unwet5/ 这是我的代码:

// myMap ='.' is a block on map
//myVisited ='*' room visited
bool isSafe(char myMap[30][30], char myVisited[30][30], int v,int h){
if(v>=0||v<30||h>=0||h<30||myMap[v][h]!='.'||myVisited[v][h]=='*')return true;
    return false;}

//3 map
//myMap contain the maze
//myVisited use to mark room visited
//myPath is final path.
bool find_path(char myMap[30][30],char myVisited[30][30],char myPath[30][30], int v,int h){
//giving h=-1 and v=-1 , find starting point.
    if(h==-1&&v==-1){
        h=h+1;
        for (v=0;v<30;v++){
        if(myMap[v][h]!='.'&& h==0) {find_path(myMap,myVisited,myPath,v,h);}
        }

    }

    myVisited[v][h]='*';    //mark room as visited.
    if(h==29){              //stop when column is 29 and mark on path
        myPath[v][h]='*';
        return true;}

    if(isSafe(myMap,myVisited,v,h-1)==true){                //if room is okie to access
        if(find_path(myMap,myVisited,myPath,v,h-1)==true){  // there is way out 
        myPath[v][h]='*';           //mark on myPath
        }
    }
    //.......same code for other room

    if(isSafe(myMap,myVisited,v,h+1)==true){                //if room is okie to access
        if(find_path(myMap,myVisited,myPath,v,h+1)==true){  // there is way out 
        myPath[v][h]='*';           //mark on myPath
        }
    }   
    if(isSafe(myMap,myVisited,v-1,h)==true){                //if room is okie to access
        if(find_path(myMap,myVisited,myPath,v-1,h)==true){  // there is way out 
        myPath[v][h]='*';           //mark on myPath
        }
    }
    if(isSafe(myMap,myVisited,v+1,h)==true){                //if room is okie to access
        if(find_path(myMap,myVisited,myPath,v+1,h)==true){  // there is way out 
        myPath[v][h]='*';           //mark on myPath
        }
    }
    if(isSafe(myMap,myVisited,v+1,h-1)==true){              //if room is okie to access
        if(find_path(myMap,myVisited,myPath,v,h-1)==true){  // there is way out 
        myPath[v][h]='*';           //mark on myPath
        }
    }
        if(isSafe(myMap,myVisited,v-1,h-1)==true){              //if room is okie to access
        if(find_path(myMap,myVisited,myPath,v-1,h-1)==true){    // there is way out 
        myPath[v][h]='*';           //mark on myPath
        }
    }
            if(isSafe(myMap,myVisited,v-1,h+1)==true){              //if room is okie to access
        if(find_path(myMap,myVisited,myPath,v-1,h+1)==true){    // there is way out 
        myPath[v][h]='*';           //mark on myPath
        }
    }
    myVisited[v][h]='.';
        return false;//back track 
return false;}

【问题讨论】:

  • 通过调试器运行你的代码,你应该会发现错误。
  • 尝试用一个 3 X 3 的小迷宫来运行它,行得通吗?尝试调试它。什么线压碎了?
  • if(v&gt;=0||v&lt;30||h&gt;=0||h&lt;30||myMap[v][h]!='.'||myVisited[v][h]=='*')return true; 你在这里搞糊涂了。
  • 您将参数v 用作循环变量,稍后将其再次视为输入,此时它可能包含超出棋盘末端的索引。灾难的秘诀。
  • 我已经按照 Itay 的建议修复了 isSafe,但是,地图只打印出起点,没有其他内容。我的 find_path 有什么问题吗????

标签: c maze recursive-backtracking


【解决方案1】:

试试这个

bool isSafe( char myMap[ 30 ][ 30 ], char myVisited[ 30 ][ 30 ], int v,int h ) {
    bool ret_val = true;

    ret_val = ( v >= 0 ) && ( v < 30 ) && ( h >= 0 ) && ( h > 30 ) && ( myMap[ v ][ h ] != '.' ) && ( myVisited[ v ][ h ] != '*' );

    return ret_val;

}

已编辑:感谢@NiBZ - 看起来有点乱,但现在不会导致段错误

【讨论】:

  • 谢谢,它没有更多的分割错误,但地图只打印起点,没有别的。我的 find_path 函数有问题
  • 在这种情况下,myMap[v][h]myVisited[v][h] 将始终被评估,即使 vh 超出范围。单行 (bool ret_val = (v&gt;=0) &amp;&amp; (v&lt;30) ... &amp;&amp; (myVisited[v][h] == '*');) 将在第一个错误条件下停止评估。
  • 你知道我的 find_path 函数有什么问题吗?好像不行???
  • 我想你把它改成myVisited[ v ][ h ] != '*'