好的,所以我在Python中实现了Djakstra's shortest path algorithm并且它正常工作(距离计算正确),但我希望它也能返回新的优化图。这是我的工作:
nodes = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I')
graph = {'A': {'B': 4, 'H': 8},
'B': {'A': 4, 'C': 8, 'H': 11},
'C': {'B': 8, 'D': 7, 'I': 2, 'F': 4},
'D': {'C': 7, 'E': 9, 'F': 14},
'E': {'D': 9, 'F': 10},
'F': {'E': 10, 'D': 14, 'C': 4, 'G': 2},
'G': {'F': 2, 'H': 1, 'I': 6},
'H': {'A': 8, 'B': 11, 'I': 7, 'G': 1},
'I': {'C': 2, 'H': 7, 'G':6}}
inf = 5000 #truncating inf as 5000
sptset = {} #shortest path tree set (SPT)
main = {} #main dict with nodes and their distances
source = 'A'
#initialization of source (starting point)
for node in nodes:
main[node] = inf
main[source] = 0
sptset[source] = 0
temp_set = {source: 0}
path = {source: None}
current = None
while len(sptset)<len(nodes):
path[min(temp_set, key=temp_set.get)] = current
#keeping track of the path
current = min(temp_set, key=temp_set.get)
#choosing the next node to check as the minimum of the mainset
#(IF node IS NOT in stpset)
sptset[current] = main.get(current)
#adding the current node to stpset
for neighbor in graph[current].keys():
#for every adjacent node of the current
alt = main.get(current) + graph[current].get(neighbor)
#calculate the distance of current node(from the mainset) + wight to neighbor(from graph)
if alt < main.get(neighbor):
#if that sum is less than the distance of neighbor (from the mainset), then update it in mainset
main[neighbor] = alt
temp_set = {}
for key in main.keys():
if key not in sptset.keys():
temp_set[key] = main.get(key)
#this dictionary is being used to reconstruct the mainset WITHOUT the nodes already in stpset
#(this is done so that the algorithm can be reiterated and a new current node can be chosen)
print path
print sptset
现在路径打印完成后,您可以清楚地知道算法路径,而不是节点的真实路径。如何根据我刚刚计算的距离找出节点的真实路径?
答案 0 :(得分:0)
每当更新最小距离时,您都需要更新父级。因此,不要在主循环的顶部放置path[min(temp_set, key=temp_set.get)] = current
,而是在与距离相同的if
块下进行父更新:
if alt < main.get(neighbor):
#if that sum is less than the distance of neighbor (from the mainset), then update it in mainset
path[neighbor] = current
main[neighbor] = alt
答案 1 :(得分:0)
您无需存储每个节点的路径:main
中已提供该信息。对于具有低连接性的图形,可以根据需要扫描main
以重建任何路径:
def parent_node(node):
neighbors = graph[node]
if len(neighbors) == 0:
return None
best_neighbor = min(neighbors, key=lambda neighbor: main[neighbor])
if main[best_neighbor] >= main[node]:
return None
return best_neighbor
def shortest_path(node):
path = []
while node:
path.append(node)
node = parent_node(node)
path.reverse()
return path
farthest_node = max(graph, key=lambda node: main[node])
print shortest_path(farthest_node)