BFS algorithm to optimize two-way width-first search

Bidirectional breadth-first search (Bidirectional BFS) algorithm is applicable to the following scenarios:

  1. Undirected graph
  2. The length of all the sides are all the same length or 1
  3. At the same time it gives the start and end points

When the above three conditions are met, you can use two-way width-first search to find the shortest distance between the starting point and end point.

Algorithm Description

Two-way nature or breadth-first search BFS, but became the starting point and end point be extended to the end to the starting point at the same time, until the same sub-node appears on both directions, the search ends. A queue saved state from the start of the search, another state of preservation from the beginning of the end, if the two sides intersect, then the search ends: we may be implemented using a queue. Beginning to the end of the shortest distance is the distance from the starting point to the end point of the intersection node to node distance of the intersection of and.

Q. Does bidirectional BFS can really improve efficiency?
Suppose way BFS search needs to reach the end N layer, each layer is determined an amount of X, then the total calculation amount of  X-N ^ X- N. BFS if it were a two-way, front and rear need to search each N / 2 layer, the total calculation in an amount of  2 * X-^ {N / 2} 2 * X- N / 2. If N is relatively large and X is not 1, the amount of computation compared to the one-way BFS can be greatly reduced, almost can be reduced to the order of the square root of the original size.

Import the deque Collections from 

DEF doubleBFS (Start, End): 
    IF == Start End: 
        return. 1 

    # start and end, respectively, from the beginning of the two queues BFS 
    startQueue, the deque endQueue = (), the deque () 
    startQueue.append (Start) 
    endQueue .append (End) 
    STEP = 0 

    # from the set start point and the end point from the start node are visited 
    startVisited, endVisited = sET (), sET () 
    startVisited.add (start) 
    endVisited.add (End) 
    the while len (startQueue) len and (endQueue): 
        startSize, endSize = len (startQueue), len (endQueue) 
        # traversed by layer 
        STEP + =. 1 
        for _ in Range (startSize): 
            CUR = startQueue.popleft () 
            for neighbor in cur.neighbors:
                if neighbor in startVisited: # 重复节点
                    continue
                elif neighbor in endVisited: # 相交
                    return step
                else:
                    startVisited.add(neighbor)
                    startQueue.append(neighbor)
        step += 1
        for _ in range(endSize):
            cur = endQueue.popleft()
            for neighbor in cur.neighbors:
                if neighbor in endVisited:
                    continue
                elif neighbor in startVisited:
                    return step
                else:
                    endVisited.add(neighbor)
                    endQueue.append(neighbor)
    
    return -1

  

Study Advice

Bidirectional BFS is not to master the difficult, complex algorithm a little bit (double the amount of code relative way BFS), on the one hand to grasp the algorithm proficiency to deepen the common BFS, on the other hand, you can basically write once Remember, if you asked the question of how to optimize the BFS in the interview, Bidirectional BFS is almost standard answer.

Reference material

https://www.geeksforgeeks.org/bidirectional-search

Application examples

Shortest Path in Undirected Graph
Knight Shortest Path
Knight Shortest Path II

Guess you like

Origin www.cnblogs.com/bonelee/p/11724526.html