存储无向图中所有节点的距离(节点,开始)的算法

2024-05-21 13:54:45 发布

您现在位置:Python中文网/ 问答频道 /正文

目标是创建一个名为siz的数组,该数组存储来自起始节点的所有路径的长度。在理想情况下,我会调用f(start)并期望图中所有顶点v的siz[v]都被填满

这就是我正在使用的算法

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)

变量描述:

  1. adj[cur_nod]包含节点cur_nod的所有邻居
  2. siz[cur_nod](不是int数据类型的列表)包含从节点1到节点1的所有距离 库诺
  3. w(x,y)表示连接节点x和y的边的权重
  4. vis[nod]跟踪节点是否被访问。0表示未访问,1表示已访问

递归似乎不正确,我不知道何时实际将节点标记为已访问。此外,由于存在循环,我不希望距离包含循环。例如,A->;B->;C->;A->;D完全不应该是这样。它应该只是一个->;D或所有其他方式有一条从a到D的路径,没有经过循环

要举例说明此算法如何无法按预期工作,请执行以下操作:

如果我将节点和边权重输入为w(1,2)=1,w(2,3)=2,w(2,4)=7和w(3,4)=1

然后siz=[-1]、[0]、[1]、[3]、[4]]。(请注意,我最初设置了siz[1]=0和siz[0]=-1,因为我的起始节点是1,数组是0索引的,但我需要它作为1索引),而理想的siz应该是[[-1]、[0]、[1]、[3,9]、[4,8]]


Tags: ingt路径算法nodefor节点数组
1条回答
网友
1楼 · 发布于 2024-05-21 13:54:45
你可以做的就是简单地考虑你正在穿越的当前路径。 对于上次访问的节点,创建相应的新路径并将其添加到我重命名为siz的“node_paths”。 然后对每个邻居递归

由于给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)]}

在上面的代码中,我存储了路径和加权和以简化调试,但您显然可以放弃存储的路径

有几点:

  • 调试时,避免询问用户输入和硬代码,这有助于再现性和加快尝试
  • 1,2,4,8的一个很好的性质是(给定二进制表示),你所取的任何组合(数字之间)都会产生一个不同的和,它“唯一地”描述了你的路径(即使在那里我们只是有路径可供使用)
  • 我没有遵循你的算法精神,因为我认为它对于上面的菱形图是失败的(即使有向图中没有循环)(因为我们可能会累积相同的路径)(但我只是猜测,没有测试猜测,可能是错误的)

相关问题 更多 >