Java 我认为我的BFS将所有有效坐标添加到列表中,而不仅仅是最短路径

Java 我认为我的BFS将所有有效坐标添加到列表中,而不仅仅是最短路径,java,breadth-first-search,Java,Breadth First Search,所以我正在研究BFS算法,在二维二元迷宫中找到最短路径,并以坐标的形式打印路径。代码正在运行,但肯定有一些错误 迷宫坐标基本上有真值或假值(其中墙为假)。迷宫中的坐标以名为Pos的自定义类的形式给出 我的目标是找到路径,在列表中添加点(以Pos的形式),然后返回数组列表ArrayList path 以下是我目前得到的信息: import java.util.ArrayList; import java.util.ArrayDeque; import java.util.Queue; class

所以我正在研究BFS算法,在二维二元迷宫中找到最短路径,并以坐标的形式打印路径。代码正在运行,但肯定有一些错误

迷宫坐标基本上有真值或假值(其中墙为假)。迷宫中的坐标以名为
Pos
的自定义类的形式给出

我的目标是找到路径,在列表中添加点(以Pos的形式),然后返回数组列表
ArrayList path

以下是我目前得到的信息:

import java.util.ArrayList;
import java.util.ArrayDeque;
import java.util.Queue;

class Node {
    int x;
    int y;
    int d;

    Node(int x, int y, int d) {
        this.x = x;
        this.y = y;
        this.d = d;
    }
};

public class Problem3{

    private static final int r[] = {-1, 0, 0, 1};
    private static final int c[] = {0, -1, 1, 0};

    public static ArrayList<Pos> findPath(Pos start, Pos end, boolean maze[][]){
        ArrayList<Pos> path = new ArrayList<Pos>();
        path.add(start);

        // Get the x and y values from both start and end Pos
        // currX and currY is initially start Pos
        int currX = start.x;
        int currY = start.y;
        int endX = end.x;
        int endY = end.y;

        // Set to size of maze
        boolean[][] visited = new boolean[6][6];

        Queue<Node> q = new ArrayDeque<>();

        visited[currX][currY] = true;
        q.add(new Node(currX, currY, 0));

        int min_d = Integer.MAX_VALUE;

        while (!q.isEmpty()) {
        // Pop front node and process
            Node node = q.poll();

            currX = node.x;
            currY = node.y;
            int d = node.d;

            // If end is found, stop
            if (currX == endX && currY == endY)
            {   

                path.add(end);
                min_d = d;
                break;
            }

            // check all 4 directions from curr cell
            for (int k = 0; k < 4; k++)
            {
                if (isValid(maze, visited, currX + r[k], currY + c[k]))
                {
                    // mark as visited and add to path
                    visited[currX + r[k]][currY + c[k]] = true;
                    q.add(new Node(currX + r[k], currY + c[k], d + 1));
                    path.add(new Pos(currX, currY));
                }
            }
        }

        // If path is empty, return null. Else return path
        if (path.isEmpty()) {
            return null;
        }
        else {
            return path;
        }

    }


        // Checks if cell is traversable or visited
    private static boolean isValid(boolean maze[][], boolean visited[][], int r, int c) {
        return maze[r][c] && !visited[r][c];
    }   

}




我希望输出为:

[1,1]
[2,1]
[3,1]
[4,1]
[4,2]
但我得到的是:

[1,1]
[1,1]
[1,1]
[1,2]
[2,1]
[1,3]
[3,1]
[1,4]
[4,1]
[2,4]
[4,2]

通过查看输出,算法似乎找到了最短路径,但会将每个坐标打印两次。此外,x和y值会翻转,并且开始坐标会打印3次。非常感谢您提供的任何故障排除帮助。

您的问题是,
路径从来不会重置,只会添加到。您需要以某种方式跟踪
Pos
或级别的上一个位置

试试这个:

    while (!q.isEmpty()) {
    // Pop front node and process
        Node node = q.poll();

        currX = node.x;
        currY = node.y;
        int d = node.d;
        path.removeRange(d, path.size());
        path.add(new Pos(curX, curY));

        // If end is found, stop
        if (currX == endX && currY == endY)
        {   
            min_d = d;
            break;
        }

        // check all 4 directions from curr cell
        for (int k = 0; k < 4; k++)
        {
            if (isValid(maze, visited, currX + r[k], currY + c[k]))
            {
                // mark as visited and add to path
                visited[currX + r[k]][currY + c[k]] = true;
                q.add(new Node(currX + r[k], currY + c[k], d + 1));
            }
        }
    }

while(!q.isEmpty()){
//Pop前端节点和进程
Node=q.poll();
currX=node.x;
currY=node.y;
//如果找到结束,请停止
如果(currX==endX&&currY==endY)
{   
ArrayList路径=新建ArrayList();
做{
添加(0,新位置(node.x,node.y));
node=node.prev;
}while(node!=null);
返回路径;
}
//检查当前单元格的所有4个方向
对于(int k=0;k<4;k++)
{
if(有效(迷宫、访问、currX+r[k]、currY+c[k]))
{
//标记为已访问并添加到路径
已访问[currX+r[k]][currY+c[k]]=true;
q、 添加(新节点(currX+r[k],currY+c[k],节点));
}
}
}
返回null;

您是否尝试过调试代码以了解它返回这些坐标的原因?不,我没有这样做。我现在就开始,看看是否能理解这个path.removeRange(d,path.size());具有受保护的访问权限。我使用了path.subList(d,path.size()).clear();相反,但当算法进入不匹配的路径时失败,必须还原部分路径并选择另一条路径。@n1t4chi正确,对此表示抱歉。在这种情况下,我将把
节点
与其前身链接起来。可通过在末端反转链条来构建路径。
    while (!q.isEmpty()) {
    // Pop front node and process
        Node node = q.poll();

        currX = node.x;
        currY = node.y;
        int d = node.d;
        path.removeRange(d, path.size());
        path.add(new Pos(curX, curY));

        // If end is found, stop
        if (currX == endX && currY == endY)
        {   
            min_d = d;
            break;
        }

        // check all 4 directions from curr cell
        for (int k = 0; k < 4; k++)
        {
            if (isValid(maze, visited, currX + r[k], currY + c[k]))
            {
                // mark as visited and add to path
                visited[currX + r[k]][currY + c[k]] = true;
                q.add(new Node(currX + r[k], currY + c[k], d + 1));
            }
        }
    }
class Node {
    int x;
    int y;
    Node prev;

    Node(int x, int y, Node prev) {
        this.x = x;
        this.y = y;
        this.prev = prev;
    }
};
    while (!q.isEmpty()) {
    // Pop front node and process
        Node node = q.poll();

        currX = node.x;
        currY = node.y;

        // If end is found, stop
        if (currX == endX && currY == endY)
        {   
            ArrayList<Pos> path = new ArrayList<>();
            do {
                path.add(0, new Pos(node.x,node.y));
                node = node.prev;
            } while (node != null);
            return path;
        }

        // check all 4 directions from curr cell
        for (int k = 0; k < 4; k++)
        {
            if (isValid(maze, visited, currX + r[k], currY + c[k]))
            {
                // mark as visited and add to path
                visited[currX + r[k]][currY + c[k]] = true;
                q.add(new Node(currX + r[k], currY + c[k], node));
            }
        }
    }
    return null;