Python 用Dijkstra求循环图的最短路径
我有一个循环有向图。下面是以python dict表示的图形Python 用Dijkstra求循环图的最短路径,python,python-3.x,graph-algorithm,dijkstra,Python,Python 3.x,Graph Algorithm,Dijkstra,我有一个循环有向图。下面是以python dict表示的图形 graph = { 'A': {'B': 5, 'D': 5, 'E': 7 }, 'B': {'C': 4}, 'C': {'D': 8, 'E': 2}, 'D': {'C': 8, 'E': 6}, 'E': {'B': 3} } 我写了一个简单的Dijkstra最短路径的实现。这似乎适用于给定的两点。下面是我
graph = {
'A': {'B': 5, 'D': 5, 'E': 7 },
'B': {'C': 4},
'C': {'D': 8, 'E': 2},
'D': {'C': 8, 'E': 6},
'E': {'B': 3}
}
我写了一个简单的Dijkstra最短路径的实现。这似乎适用于给定的两点。下面是我的实现
def shortestpath(self, start, end, visited=[],distances={},predecessors={}):
# initialize a big number
maxint = 10000
if start==end:
path=[]
while end != None:
path.append(end)
end=predecessors.get(end, None)
return distances[start], path[::-1]
# detect if it's the first time through, set current distance to zero
if not visited: distances[start]=0
# process neighbors as per algorithm, keep track of predecessors
for neighbor in self.graph[start]:
if neighbor not in visited:
neighbordist = distances.get(neighbor,maxint)
tentativedist = distances[start] + self.graph[start][neighbor]
if tentativedist < neighbordist:
distances[neighbor] = tentativedist
predecessors[neighbor]=start
# neighbors processed, now mark the current node as visited
visited.append(start)
# finds the closest unvisited node to the start
unvisiteds = dict((k, distances.get(k,maxint)) for k in self.graph if k not in visited)
closestnode = min(unvisiteds, key=unvisiteds.get)
# now we can take the closest node and recurse, making it current
return self.shortestpath(closestnode,end,visited,distances,predecessors)
它将给我的路径和最短的重量
(9,['A','B','C']
在这种情况下。
但是,只要我最短路径('B','B')
程序就会中断。
现在有一条从
B到B
的最短路径,因为它是一个循环图,路径是B-C-E-B。我只是不知道如何检查它,并相应地修改Dijktra的算法,让它检查像这样的循环情况。非常感谢您的任何建议。谢谢:)严格来说,从B
到B
的最短距离是零,因为您已经在那里了。如果要查找循环距离,最简单的解决方案可能是添加一个新的虚拟节点Bs
,该节点具有与B
相同的出站边缘。然后你所要做的就是找到从Bs
到B
的最短路径。我认为还可以使用更通用的解决方案,例如,修改算法以不允许总距离为零。此外,您应该用一个集合替换访问的列表,以减少渐进运行时间,因为当访问的节点列表增加时,识别不在访问列表中的节点将花费太长时间(线性时间,这将使整个算法>O(n^2)
。实现这一点的标准方法是检查开始节点是否为目标节点,即如果开始==end,则没有返回的路径。那么为什么要检查self==end?因为这是一个循环图。
shortestpath('A', 'C')