从节点A开始,我们看到这个图形如何变成树。A是停留在第0层的起始节点,然后B和C在第1层上,然后D和E在第2层上。这是BFS将遍历此图的顺序。如果我们使用BFS遍历此图,则顺序为:A - > B - > C - > D - > E.仔细观察树,我们将看到B和C以及E和D之间存在一些联系。这是因为我们的图包含循环。但是如果我们想要以最佳方式遍历它,我们就不应该再次访问已经访问过的节点。因此,选择要访问的节点的一个条件是不可访问的。
1BFS(G, s, goal) 2 Let Q be queue 3 Q.enqueue(s) 4 Mark s as visited 5while (Q isnot empty) 6 //Removing that vertex from queue 7 v = Q.dequeue() 8 If v is goal 9return “found the goal” 10 //processing all the neighbours of v 11for all neighbours w of v in Graph G 12if w isnot visited 13 //Stores w in Q to further visit its neighbour 14 Q.enqueue(w) 15 mark w as visited
因此,使用此算法,如果起始节点和目标之间至少存在路径,我们就能够找到任何节点。
寻找最短路径
让我们通过在顶点上添加一些成本来更改我们的图形。
现在我们想要在成本最低的路径上从A到D。我们看到从A到D有多种方式。我们可以走这条路,A - > B - > D,成本为20,或者我们可以选择A - > C - > B - > D,成本更低16但是还有另一条成本最低的路径3,A - > C - > E - > D.那么,我们应该怎样做才能找到这条路?我们需要改变获取下一个节点的方式。在经典的BFS算法中,我们使用FIFO队列顺序选择下一个要访问的节点(先进先出,然后进入)。我们最终会找到目标而不是最便宜的路径。为了在成本最低的路径上实现目标,我们需要对从队列中访问下一个节点的方式进行更改。我将向您呈现的算法称为统一成本搜索,它是Dijkstra的略微修改版本,我们在找到目的地时停止。经典的Dijkstra算法继续访问所有节点,直到队列为空,找到从起始节点到图中每个其他节点的最低成本。与BFS的不同之处在于,我们必须存储一个新值,表示从开始到当前访问节点的总成本。FIFO规则不会对队列进行排序,相反,我们将根据当前成本到目前为止的值对队列进行排序,优先考虑到目前为止成本最低的未访问节点。我们来看看代码:
1UniformCostSrearch(G, s) 2 s.costSoFar = 0; 3for all nodes w in G except s 4 w.costSoFar = Int.maxInt 5 Let Q be a priority queue ordered by cost_so_far 6 Q.enqueue(s) 7while (Q isnot empty) 8 //Removing that vertex from queue 9 v = Q.dequeue() 10 If v is goal 11return “found the goal” 12 //processing all the neighbours of v 13for all neighbours w of v in Graph G 14 currentCost = dist[v,w] 15 newCost = v.costSoFar + currentCost; 16 If (newCost < w.costSoFar) 17 w.costSoFar = newCost ; 18 Q.enqueue(w)
1TreeSearch(G, s) 2 s.costSoFar = 0; 3for all nodes w in G except s 4 w.costSoFar = Int.maxInt 5 Let frontier be a priority queue ordered by the cost_so_far 6 frontier.enqueue(s) 7while (frontier isnot empty) 8 //Removing that vertex from frontier,whose neighbour will be visited now 9 v = frontier.dequeue() 10 If v is goal 11return “found the goal” 12 //processing all the neighbours of v 13for all neighbours w of v in Graph G 14 currentCost = dist[v,w] 15 newCost = v.costSoFar + currentCost; 16 If (newCost < w.costSoFar) { 17 w.costSoFar = newCost ; 18 frontier.enqueue(w)