先直观的感受一下,Dijkstra算法和双向Dijkstra算法的区别。
来源:https://www.youtube.com/watch?time_continue=44&v=8Jjdp6f7oaE&feature=emb_logo
双向Dijstra算法的思想是:
def findShortestPath_BiDijkstra(self, start, end):
closed = set()
forward_pq = queue.PriorityQueue()
backward_pq = queue.PriorityQueue()
forward_pred = {}
backward_pred = {}
forward_min_dist = {}
forward_min_dist[start] = 0
backward_min_dist = {}
backward_min_dist[end] = 0
forward_pq.put((0,start))
backward_pq.put((0, end))
shortest_path = []
path_find = False
meet_node = None
while forward_pq.qsize() != 0 or backward_pq.qsize() != 0:
if forward_pq.qsize() != 0:
dist, u = forward_pq.get()
if u in closed:
path_find = True
meet_node = u
break
closed.add(u)
if u not in self.__graph_dict:
continue
for to_node, to_weight in self.__graph_dict[u].items():
if to_node in closed:
continue
newdist = dist + to_weight
if to_node in forward_min_dist:
if newdist < forward_min_dist[to_node] :
forward_min_dist[to_node] = newdist
forward_pred[to_node] = u
else:
forward_min_dist[to_node] = newdist
forward_pred[to_node] = u
forward_pq.put((newdist, to_node))
if backward_pq.qsize() != 0:
dist, u = backward_pq.get()
if u in closed:
path_find = True
meet_node = u
break
closed.add(u)
if u not in self.__reverse_graph_dict:
continue
for to_node, to_weight in self.__reverse_graph_dict[u].items():
if to_node in closed:
continue;
newdist = dist + to_weight
if to_node in backward_min_dist:
if newdist < backward_min_dist[to_node] :
backward_min_dist[to_node] = newdist
backward_pred[to_node] = u
else:
backward_min_dist[to_node] = newdist
backward_pred[to_node] = u
backward_pq.put((newdist, to_node))
if path_find:
path = self.extractPath(meet_node, forward_pred)
shortest_path.extend(path)
path = self.extractPath(meet_node, backward_pred)
path.reverse()
shortest_path.extend(path[1:])
return shortest_path
代码效果测试:
g = { "0" : {"1":4, "2":1},
"2" : {"1":2, "3":5},
"1" : {"3":1},
"3" : {"4":3}
}
graph = Graph(g)
print('The path from vertex "0" to vertex "3":')
path = graph.findShortestPath_Dijkstra("0", "3")
print(path)
print('The bidirectional path from vertex "0" to vertex "3":')
path = graph.findShortestPath_BiDijkstra("0", "3")
print(path)
算法的输入结果如下,可以看到二者的规划结果是相同的。
The dijkstra path from vertex "0" to vertex "3":
['0', '2', '1', '3']
The bidirectional path from vertex "0" to vertex "3":
['0', '2', '1', '3']
来源:https://www.youtube.com/watch?v=1oVuQsxkhY0&feature=emb_logo
推荐一个在线动态交互的路径规划网站,用户可自行构造障碍物和不同的路线规划算法,比较算法的效果:
路径规划算法测试对比,来源:http://qiao.github.io/PathFinding.js/visual/