简体   繁体   中英

BFS reconstructing the path to get shortest path

I would like to construct a shortest path from a Breadth First Search. I have implemented the BFS in Java code (as shown below), but now I do not know how to reconstruct the path to get the shortest path from the implementation of the code.

While I know I have to keep an array of parents, I do not know where to put it in my code. Basically, I would like to trace back the shortest path using BFS from the start point to goal point. Note that I am using a 2D array.

Am I doing it correctly? Can someone please help me with that?

public ArrayList<Point> shortestPath=new ArrayList<>();
public ArrayList<Point> BFS(Point start, Point end){
   int[][] distanceBoard=new int[50][50]; Point current,parent;
    for(int i=0;i<distanceBoard.length;i++)
        for(int j=0;j<distanceBoard.length;j++) distanceBoard[i][j]=Integer.MAX_VALUE;
    distanceBoard[start.getX()][start.getY()]=0;
    LinkedList<Point> q=new LinkedList<>();
    q.addFirst(start);
    while(!q.isEmpty()){
        current=q.getFirst();
        if((new Point(current.getX(),current.getY()))==end) return shortestPath;
        q.removeFirst();
        for(Point point:current.getNeighbours()){
            if(distanceBoard[point.getX()][point.getY()]==Integer.MAX_VALUE){
                distanceBoard[point.getX()][point.getY()]=distanceBoard[current.getX()][current.getY()]+1;
                parent=current;
                q.addLast(point);
            }
            shortestPath.add(current);
        }
    }return null;
}

To backtrack you can just use the parent of the destination point and continue until you reach the place you started... something like

ArrayList < vertex > points = new ArrayList < > ();
while ((current.x != startx) || (current.y != starty)) {
  points.add(current);
  current = current.parent;
}

where startx and starty is the (x,y) position you start from in your grid. You want to do this after you have found the destination your looking for ie after you break out of the while(!q.isEmpty()){...} .

while (!q.isEmpty()) {
  current = q.dequeue();
  if (current.x == targetx && current.y == targety) break; //quite when path is found
  ...
}
ArrayList < vertex > vertices = new ArrayList < > ();
while ((current.x != startx) || (current.y != starty)) {
  vertices.add(current);
  current = current.parent;
}

So the parent Point is a way of remembering where you came from and so if you have the destination Point then you should have the destination Point 's parent (or previous position) and once you have the destination Point 's parent you want to find the destination Point 's parent parent and so on until you have the Point you began the search at. I also, just to add to your confusion, made a mistake in the while ((current.x != startx)...) so instead of it being while ((current.x != startx) && (current.y != starty)) i changed it to while ((current.x != startx) || (current.y != start)) since you don't want to stop iterating when for example you have just the correct y-value, you want it to stop when both sides are false ie when both current.x != startx and current.y != start are false.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM