我目前有一个有效的Dijkstra算法,但是我想在同一张“地图”(相同的障碍物等)上找到多个最短路径,并且每次起点都相同(因此终点位置不同)。现在,我必须多次运行该算法才能获得所有路径,即使(如果我对算法的理解是正确的)我应该只运行一次算法就已经具有该信息。我将如何在代码中实现呢? (如何仅通过运行Dijkstra来获得多个路径?)
我试图找到一种方法,将多个末端位置作为输入,但还没有完全找到一种方法。
def dijsktra(graph, initial, end):
# shortest paths is a dict of nodes
# whose value is a tuple of (previous node, weight)
shortest_paths = {initial: (None, 0)}
current_node = initial
visited = set()
while current_node != end:
visited.add(current_node)
destinations = graph.edges[current_node]
weight_to_current_node = shortest_paths[current_node][1]
for next_node in destinations:
weight = graph.weights[(current_node, next_node)] + weight_to_current_node
if len(shortest_paths) >= 2:
#print(shortest_paths[-1], shortest_paths[-2])
pass
if next_node not in shortest_paths:
shortest_paths[next_node] = (current_node, weight)
#print(destinations, shortest_paths[next_node])
else:
current_shortest_weight = shortest_paths[next_node][1]
if current_shortest_weight > weight:
shortest_paths[next_node] = (current_node, weight)
next_destinations = {node: shortest_paths[node] for node in
shortest_paths if node not in visited}
if not next_destinations:
return "Route Not Possible"
# next node is the destination with the lowest weight
current_node = min(next_destinations, key=lambda k: next_destinations[k][1])
# Work back through destinations in shortest path
path = []
while current_node is not None:
path.append(current_node)
next_node = shortest_paths[current_node][0]
current_node = next_node
# Reverse path
path = path[::-1]
return path
所以我这样打:
for location in end_locations:
path = dijkstra(graph, start, location)
我想这样打电话:
paths = dijkstra(graph, start, end_locations)
这里是图类,因为注释中有请求:
class Graph():
def __init__(self):
"""
self.edges is a dict of all possible next nodes
e.g. {'X': ['A', 'B', 'C', 'E'], ...}
self.weights has all the weights between two nodes,
with the two nodes as a tuple as the key
e.g. {('X', 'A'): 7, ('X', 'B'): 2, ...}
"""
self.edges = defaultdict(list)
self.weights = {}
def add_edge(self, from_node, to_node, weight):
# Note: assumes edges are bi-directional
self.edges[from_node].append(to_node)
self.edges[to_node].append(from_node)
self.weights[(from_node, to_node)] = weight
self.weights[(to_node, from_node)] = weight
我需要输出为多路径,但现在它仅适用于一个。
答案 0 :(得分:0)
到达终点时不要停下来,而要到达每个预期位置时都不要停下来。 每次到达某个位置时,请保存路径。
def dijsktra(graph, initial, ends):
# shortest paths is a dict of nodes
# whose value is a tuple of (previous node, weight)
shortest_paths = {initial: (None, 0)}
current_node = initial
visited = set()
node_to_visit = ends.copy()
paths = []
while node_to_visit:
visited.add(current_node)
destinations = graph.edges[current_node]
weight_to_current_node = shortest_paths[current_node][1]
for next_node in destinations:
weight = graph.weights[(current_node, next_node)] + weight_to_current_node
if len(shortest_paths) >= 2:
# print(shortest_paths[-1], shortest_paths[-2])
pass
if next_node not in shortest_paths:
shortest_paths[next_node] = (current_node, weight)
# print(destinations, shortest_paths[next_node])
else:
current_shortest_weight = shortest_paths[next_node][1]
if current_shortest_weight > weight:
shortest_paths[next_node] = (current_node, weight)
next_destinations = {node: shortest_paths[node] for node in
shortest_paths if node not in visited}
if not next_destinations:
return "Route Not Possible"
# next node is the destination with the lowest weight
current_node = min(next_destinations, key=lambda k: next_destinations[k][1])
if current_node in node_to_visit:
node_to_visit.remove(current_node)
# Work back through destinations in shortest path
path = []
last_node = current_node
while last_node is not None:
path.append(last_node)
next_node = shortest_paths[last_node][0]
last_node = next_node
# Reverse path
path = path[::-1]
paths.append(path)
return paths