这可能是最初的初学者问题,但一直在玩图表并且已经在各种练习中实施BFS搜索。我无法弄清楚如何实际跟踪我访问过的边的权重,以便创建图的最小完全跨越。我的图表格式为:
{0: [(1, 1), (2, 1)], 1: [(0, 1), (2, 1)], 2: [(1, 1), (0, 1)]}
第一个顶点为0,相邻顶点为1和2,权重分别为1和1。因此,更清楚地说,图表字典中的键表示顶点,键值中的每个元组表示顶点,权重对。
所以我的BFS功能就是:
def bfs(graph, start):
"""returns total weight needed to visit
each vertice in the graph with the minimum
overall weight possible"""
if [] in graph.values():
return "Not Possible"
weight = 0
visited, queue = set(), [start]
while queue:
vertex = queue.pop(0)
if vertex not in visited:
visited.add(vertex)
for node in graph[vertex]:
queue.append(node[0])
weight += node[1]
return weight
目前使用我的原始图表时,此函数会返回6
,它应该是2
。我认为这是因为它迭代每个顶点并添加相邻权重,即使它们已被访问过。
这实际上也不会选择最小加权路径,它只跟踪它所采用的路径的权重,无论可能是什么。我该如何解决这个问题?
更长的例子:
{0: [(1, 5), (2, 7), (3, 12)], 1: [(0, 5), (2, 9), (4, 7)], 2: [(0, 7), (1, 9), (3, 4), (4, 4), (5, 3)], 3: [(0, 12), (2, 4), (5, 7)], 4: [(1, 7), (2, 4), (5, 2), (6, 5)], 5: [(2, 3), (3, 7), (4, 2), (6, 2)], 6: [(4, 5), (5, 2)]}
这会产生134
的权重,其正确答案应为23
是否有一些我缺少的算法可以跟踪加权边缘并从中选择最佳路径?
我知道Dijkstra的算法,但据我所知,它适用于具有指定开始和结束的路径,而不是完整的图形跨度?
答案 0 :(得分:0)
Dijkastra的算法和bfs在查找两个顶点之间的最小路径时非常有用。但是,如果要查找最小生成树,请查看Kruskal算法。
这是链接: https://en.wikipedia.org/wiki/Kruskal%27s_algorithm
伪代码:
KRUSKAL(G):
1 A = ∅
2 foreach v ∈ G.V:
3 MAKE-SET(v)
4 foreach (u, v) in G.E ordered by weight(u, v), increasing:
5 if FIND-SET(u) ≠ FIND-SET(v):
6 A = A ∪ {(u, v)}
7 UNION(u, v)
8 return A
使用union-find(脱节集)数据结构实现。