![](/img/trans.png)
[英]Shortest and longest path in a topologically sorted unweighted directed acyclic graph using an adjacency matrix (Python, or pseudo-code)
[英]Unweighted directed graph distances
假设我有一个未加权的有向图。 我想知道是否有一种方法可以存储起始节点和图中所有剩余节点之间的所有距离。 我知道 Dijkstra 的算法可能是一种选择,但我不确定这是否是最好的,因为我正在使用一个非常大的图(约 100k 个节点),而且它是一个未加权的图。 到目前为止,我的任务是执行 BFS,同时尝试存储所有距离。 这是一种可行的方法吗?
最后,由于我对图论还很陌生,有人可能会为我指出正确的方向,以实现此类问题的良好 Python 实现吗?
如果您的数据结构包含在起始节点标识符上索引的每个起始节点的结束节点列表,则绝对可行并且非常快:
这是一个使用字典作为边的示例: {startNode:list of end nodes}
from collections import deque
maxDistance = 0
def getDistances(origin,edges):
global maxDistance
maxDistance = 0
distances = {origin:0} # {endNode:distance from origin}
toLink = deque([origin]) # start at origin (distance=0)
while toLink:
start = toLink.popleft() # previous end, will chain to next
dist = distances[start] + 1 # new next are at +1
for end in edges[start]: # next end nodes
if end in distances: continue # new ones only
distances[end] = dist # record distance
toLink.append(end) # will link from there
maxDistance = max(maxDistance,dist)
return distances
这对每个节点(不包括无法访问的节点)进行一次迭代,并使用快速字典访问来跟踪指向新下一个节点的链接
使用一些随机测试数据(1000 万条边)......
import random
from collections import defaultdict
print("loading simulated graphs")
vertexCount = 100000
edgeCount = vertexCount * 100
edges = defaultdict(set)
edgesLoaded = 0
minSpan = 1 # vertexCount//2
while edgesLoaded<edgeCount:
start = random.randrange(vertexCount)
end = random.randrange(vertexCount)
if abs(start-end) > minSpan and end not in edges[start]:
edges[start].add(end)
edgesLoaded += 1
print("loaded!")
表现:
# starting from a randomly selected node
origin = random.choice(list(edges.keys()))
from timeit import timeit
t = timeit(lambda:getDistances(origin,edges),number=1)
print(f"{t:.2f} seconds for",edgeCount,"edges", "max distance = ",maxDistance)
# 3.06 seconds for 10000000 edges max distance = 4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.