这是一个经典的广度优先搜索问题,其中你有一个无向、无权图,想要找到两个顶点之间的最短路径。
一些关于广度优先搜索的有用链接:
你需要注意一些边缘情况:
- 源顶点和目标顶点之间没有路径
- 源顶点和目标顶点相同
我假设你的边缘列表是一个字典列表或列表列表,例如:
[[4191, 949], [3002, 4028, 957], [2494, 959, 3011], [4243, 965], [1478], ...]
或者
{ 0: [4191, 949],
1: [3002, 4028, 957],
2: [2494, 959, 3011],
3: [4243, 965],
4: [1478], ...}
我写了一些代码来展示广度优先搜索的工作原理:
import sys
import sys
import Queue
def get_shortest_path(par, src, dest):
'''
Returns the shortest path as a list of integers
par - parent information
src - source vertex
dest - destination vertex
'''
if dest == src:
return [src]
else:
ret = get_shortest_path(par, src, par[dest])
ret.append(dest)
return ret
def bfs(edgeList, src, dest):
'''
Breadth first search routine. Returns (distance, shortestPath) pair from src to dest. Returns (-1, []) if there is no path from src to dest
edgeList - adjacency list of graph. Either list of lists or dict of lists
src - source vertex
dest - destination vertex
'''
vis = set()
par = {}
distDict = {}
q = Queue.Queue()
q.put((src, 0))
par[src] = -1
vis.add(src)
while not q.empty():
(v,dist) = q.get()
distDict[v] = dist
if v == dest:
break
nextDist = dist+1
for nextV in edgeList[v]:
if nextV not in vis:
par[nextV] = v
q.put((nextV, nextDist))
vis.add(nextV)
if dest in distDict:
return (distDict[dest], get_shortest_path(par, src, dest))
else:
return (-1, [])
if __name__ == '__main__':
edgeList = {
0: [6,],
1: [2, 7],
2: [1, 3, 6],
3: [2, 4, 5],
4: [3, 8],
5: [3, 7],
6: [0, 2],
7: [1, 5],
8: [4],
}
while True:
src = int(sys.stdin.readline())
dest = int(sys.stdin.readline())
(dist, shortest_path) = bfs(edgeList, src, dest)
print 'dist =', dist
print 'shortest_path =', shortest_path
matplotlib
标签移除,因为我不认为它与绘图有关。如果您不同意,请随时恢复。 - tacaswell