使用递归在网格上进行回溯。

huangapple go评论81阅读模式
英文:

Using recursion to backtrack on a grid

问题

我会简洁地解释。我的问题是,我生成一个 d x d 方格网格。在网格的每个方格中都包含一个从 1 到 (d-1) 的随机整数。并且有一个方格包含一个 0(目标)。我随机从任何不是目标的方格开始,我可以朝着当前方格上的数字所表示的数量的任何方向移动(不能超出边界),我需要使用递归来解决这个问题。根据我开始的位置和网格的布局,达到目标可能是不可能的。

我尝试过尝试不同的算法,并偶然发现了深度优先搜索(DFS)。就我目前的情况而言,我不确定如何正确地进行“回溯”,以避免陷入无限循环。例如,如果我从一个值为 3 的方格开始,我会向右移动 3 个位置,如果我移动到的方格仍然是 3,并且不能向右移动,因为超出了边界,所以我会向左移动,然后向右移动,然后向左移动,依此类推。

以下是我递归方法的一部分,可能会陷入无限循环,我希望能够指导如何正确地避免陷入循环。我该如何追踪我之前所在的方格,并避免朝会导致循环的方向移动?

提前感谢您的帮助!

英文:

i'll keep this concise. My problem is I generate a grid of dxd squares. In ever square on the grid there contains a random integer from 1 - (d-1). And there is one square containing a 0 (the goal). I randomly start on any square that is not the goal and I can move in ANY direction the amount of spaces of the square that I'm currently on (can't go out of bounds) and I need to use recursion to solve this problem. It also may be impossible to reach the goal with where I started and the layout of the grid.

I tried playing around with different algorithms and stumbled upon DFS, with what I have now, i'm not sure how to properly "backtrack" and avoid staying in an infinite loop. For instance if i start on a square with value 3, I'll move right 3 and if the square I moved to is 3 and I cant move right because its out of bounds so i'll go back left, then right, then left and so on.

if(finalArray[startPosX][startPosY] == 0) {
    System.out.println("we did it!");
    return true;
}
else {
    if(((startPosY + squareValue) <= boardSize-1))
        MovePlayer(startPosX, startPosY + squareValue); //Move right
        
    if(((startPosY - squareValue) >= 0))
        MovePlayer(startPosX, startPosY - squareValue); //Move left
        
    if(((startPosX + squareValue) <= boardSize-1))
        MovePlayer(startPosX + squareValue, startPosY); //Move down
        
    if(((startPosX - squareValue) >= 0))
        MovePlayer(startPosX - squareValue, startPosY); //Move up
}

This is my recursive method that will end up going in an infinite loop, I'd like some guidance with how to properly be able to not get stuck in a loop. How can I keep track of the previous square I was on and not go in the direction that will cause it to loop?

Thanks in advance!

答案1

得分: 0

以下是要翻译的内容:

  1. 每当你开始沿着一条路径行走时,你需要检查返回的值,看看是否已经达到了目标,如果达到了,只需返回true,无需尝试其他路径(但如果你想找到所有可能的路径,可以继续尝试其他路径)。

  2. 通过将方块的值转为负数来标记它已被访问(或者你可以创建一个新的数组,例如 visitedArray,来标记已访问的方块,如果你不想或者不允许更改原始数组)以避免陷入无限循环:

if (finalArray[startPosX][startPosY] == 0) {
    System.out.println("我们成功了!");
    return true;
} else {
    
    // 已经访问过
    if (visitedArray[startPosX][startPosY]) return false;
 
    // 标记这个方块为已访问
    visitedArray[startPosX][startPosY] = true;

    boolean find = false;
    
    if ((startPosY + squareValue) <= boardSize-1)
        if (MovePlayer(startPosX, startPosY + squareValue)) find = true; // 向右移动,如果可以达到目标,结束递归。
        
    if (!find && (startPosY - squareValue) >= 0)
        if (MovePlayer(startPosX, startPosY - squareValue)) find = true; // 向左移动
        
    if (!find && (startPosX + squareValue) <= boardSize-1)
        if (MovePlayer(startPosX + squareValue, startPosY)) find = true; // 向下移动
        
    if (!find && (startPosX - squareValue) >= 0)
        if (MovePlayer(startPosX - squareValue, startPosY)) find = true; // 向上移动

    // 标记方块为未访问,但为了提高性能,你可以删除这一行。
    visitedArray[startPosX][startPosY] = false;

    return find;
}

希望这对你有帮助。

英文:

There are two things that need to be done to fix your algorithm:

  1. everytime you start walking into one path, you need to check the returned value to see if you have reached the goal, if you have, just return true, no need to try other paths (but if you want to find all possible paths, keep trying the rest paths).

  2. mark the square as visited by converting it's value to be negative (or you can create a new array, for example, visitedArray, to mark visited squares if you don't want to or are not allowed to change the original array) to avoid going into infiniate loop:

if(finalArray[startPosX][startPosY] == 0) {
    System.out.println(&quot;we did it!&quot;);
    return true;
}
else {
    
    //already visited
    if(visitedArray[startPosX][startPosY]) return false;
 
    //mark this square as visited
    visitedArray[startPosX][startPosY] = true;

    boolean find = false;
    
    if(((startPosY + squareValue) &lt;= boardSize-1))
        if(MovePlayer(startPosX, startPosY + squareValue)) find = true; //Move right, if goal can be reached, end recursion.
        
    if((!find &amp;&amp; (startPosY - squareValue) &gt;= 0))
        if(MovePlayer(startPosX, startPosY - squareValue)) find = true; //Move left
        
    if((!find &amp;&amp; (startPosX + squareValue) &lt;= boardSize-1))
        if(MovePlayer(startPosX + squareValue, startPosY)) find = true; //Move down
        
    if((!find &amp;&amp; (startPosX - squareValue) &gt;= 0))
        if(MovePlayer(startPosX - squareValue, startPosY)) find = true; //Move up

    //mark the square as unvisited, but to improve performance, 
    // you can delete this.
    visitedArray[startPosX][startPosY] = false;

    return find;
}

huangapple
  • 本文由 发表于 2020年10月12日 12:17:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/64311616.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定