[英]Algoriithm to store dist(node, start) for all nodes in an undirected graph
The goal is to create an array called siz that stores the length of all the paths from a starting node.目标是创建一个名为 siz 的数组,用于存储从起始节点开始的所有路径的长度。 In the ideal case, I would call f(start) and expect siz[v] to get filled up for all vertices v in the graph.
在理想情况下,我会调用 f(start) 并期望 siz[v] 为图中的所有顶点 v 填满。
This the algorithm that I am using.这是我正在使用的算法。
def f (node):
vis[node] = 1
for elem in adj[node]:
if vis[elem]==0:
for i in siz[node]:
siz[elem].append(i + w[(node,elem)])
f(elem)
Variable descriptions:变量说明:
The recursion doesn't seem correct and I don't know when to actually mark a node as visited.递归似乎不正确,我不知道何时将节点实际标记为已访问。 Also, since there are cycles, I do not want distances to include cycles.
另外,由于有循环,我不希望距离包括循环。 For instance, A -> B -> C -> A -> D should not be a case at all.
例如,A -> B -> C -> A -> D 根本不应该是一个案例。 It should just be A -> D or all other ways there is a path from A to D without going through a cycle.
它应该只是 A -> D 或所有其他方式,从 A 到 D 的路径不经过循环。
To give an example of how this algorithm doesn't work as intended:举例说明此算法如何无法按预期工作:
If I enter the nodes and the edge weights as w(1,2)=1, w(2,3)=2, w(2,4)=7 and w(3,4)=1.如果我输入节点和边权重为 w(1,2)=1, w(2,3)=2, w(2,4)=7 和 w(3,4)=1。
Then siz = [[-1], [0], [1], [3], [4]].然后 siz = [[-1], [0], [1], [3], [4]]。 (Do note that I have set siz[1]=0 and siz[0]=-1 initially since my start node is 1 and the array is 0-indexed but I need it as 1-indexed) while the ideal siz should have been [[-1], [0], [1], [3,9], [4,8]]
(请注意,我最初设置了 siz[1]=0 和 siz[0]=-1,因为我的起始节点是 1 并且数组是 0-indexed 但我需要它作为 1-indexed)而理想的尺寸应该有曾经 [[-1], [0], [1], [3,9], [4,8]]
What you may do is simply consider the current path you are traversing.您可以做的只是考虑您正在穿越的当前路径。 For the last visited node, create the corresponding new path and add it to '
siz
' which I renamed to node_paths
.对于最后访问的节点,创建相应的新路径并将其添加到我重命名为
node_paths
的“ siz
”。 Then recurse for every neighbour.然后递归每个邻居。
Since the path given to f
(see below code) is a copy you don't have to manually remove the added node (However, if eg you use path.append(node)
, when you quit f
, you would thus have to path.pop()
)由于给
f
的路径(见下面的代码)是一个副本,您不必手动删除添加的节点(但是,如果您使用path.append(node)
,当您退出f
时,您将因此必须path.pop()
)
data = [
(1, 2, 1),
(1, 3, 2),
(2, 4, 4),
(3, 4, 8),
]
adj = {}
w = {}
node_paths = {}
for (src, dst, weight) in data:
if src not in adj:
adj[src] = []
if dst not in adj:
adj[dst] = []
adj[src].append(dst)
adj[dst].append(src)
w[(src, dst)] = weight
w[(dst, src)] = weight
def f (path, weight, node, node_paths):
if node in path:
return
path_to_node = path + [node]
weight_to_node = weight + w[(path[-1], node)]
if node not in node_paths:
node_paths[node] = []
node_paths[node].append((path_to_node[1:], weight_to_node))
for neigh in adj[node]:
f(path_to_node, weight_to_node, neigh, node_paths)
node_paths = {}
start = 1
w[(-1, start)] = 0
f([-1], 0, start, node_paths)
print(node_paths)
#{1: [([1], 0)], 2: [([1, 2], 1), ([1, 3, 4, 2], 14)], 4: [([1, 2, 4], 5), ([1, 3, 4], 10)], 3: [([1, 2, 4, 3], 13), ([1, 3], 2)]}
In code above, I store both the path and the weighted sum to ease debug, but you may obviously discard the stored path在上面的代码中,我存储了路径和加权和以方便调试,但您显然可能会丢弃存储的路径
A few points:几点:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.