您可以使用 adefaultdict
从边缘/路径列表中创建“图表”:
edges = [['1', '2'], ['2', '4'], ['1', '11'], ['4', '11']]
G = defaultdict(list)
for (s,t) in edges:
G[s].append(t)
G[t].append(s)
print G.items()
输出:
[
('1', ['2', '11']),
('11', ['1', '4']),
('2', ['1', '4']),
('4', ['2', '11'])
]
请注意,我在两个方向上都添加了边,因为您正在使用无向图。因此,对于边缘 (a,b),G[a]
将包括b
并且G[b]
将包括a
.
由此,您可以使用深度优先搜索或广度优先搜索等算法来发现图中的所有路径。
在以下代码中,我使用了 DFS:
def DFS(G,v,seen=None,path=None):
if seen is None: seen = []
if path is None: path = [v]
seen.append(v)
paths = []
for t in G[v]:
if t not in seen:
t_path = path + [t]
paths.append(tuple(t_path))
paths.extend(DFS(G, t, seen[:], t_path))
return paths
您可以使用它:
G = defaultdict(list)
for (s,t) in edges:
G[s].append(t)
G[t].append(s)
print DFS(G, '1')
输出:
[('1', '2'), ('1', '2', '4'), ('1', '2', '4', '11'), ('1', '11' '), ('1', '11', '4'), ('1', '11', '4', '2')]
所以完整的代码,最后一位显示最长的路径:
from collections import defaultdict
def DFS(G,v,seen=None,path=None):
if seen is None: seen = []
if path is None: path = [v]
seen.append(v)
paths = []
for t in G[v]:
if t not in seen:
t_path = path + [t]
paths.append(tuple(t_path))
paths.extend(DFS(G, t, seen[:], t_path))
return paths
# Define graph by edges
edges = [['1', '2'], ['2', '4'], ['1', '11'], ['4', '11']]
# Build graph dictionary
G = defaultdict(list)
for (s,t) in edges:
G[s].append(t)
G[t].append(s)
# Run DFS, compute metrics
all_paths = DFS(G, '1')
max_len = max(len(p) for p in all_paths)
max_paths = [p for p in all_paths if len(p) == max_len]
# Output
print("All Paths:")
print(all_paths)
print("Longest Paths:")
for p in max_paths: print(" ", p)
print("Longest Path Length:")
print(max_len)
输出:
所有路径:
[('1', '2'), ('1', '2', '4'), ('1', '2', '4', '11'), ('1', '11' '), ('1', '11', '4'), ('1', '11', '4', '2')]
最长路径:
('1', '2', '4', '11')
('1', '11', '4', '2')
最长路径长度:
4
请注意,搜索的“起点”由DFS
函数的第二个参数指定,在这种情况下,它是'1'
.
更新: 正如评论中所讨论的,上面的代码假设您有一个起点(特别是代码使用标记为 的节点'1'
)。
如果您没有这样的起点,更通用的方法是从每个节点开始执行搜索,并采取总体最长的时间。(注意:实际上,你可能比这更聪明)
换行
all_paths = DFS(G, '1')
至
all_paths = [p for ps in [DFS(G, n) for n in set(G)] for p in ps]
会给你任何两点之间最长的路径。
(这是一个愚蠢的列表理解,但它只允许我更新一行。更清楚地说,它相当于以下内容:
all_paths = []
for node in set(G.keys()):
for path in DFS(G, node):
all_paths.append(path)
或者
from itertools import chain
all_paths = list(chain.from_iterable(DFS(G, n) for n in set(G)))
)。