Python中使用Tarjan算法求强连通分量
Tarjan 算法是求解有向图中强连通分量的经典算法之一。其基本思路是通过 DFS 遍历每个节点,并标记每个节点的遍历次序(即 DFS 序)。对于每个节点,记录其能够到达的 DFS 序最小的节点(即能够追溯到的最小祖先节点)。如果一个节点能够追溯到自己,则将其所在的强连通分量中的所有节点找出来。具体的实现中,常常通过维护一个栈来记录当前搜索的路径,以及维护一个标记数组记录每个节点的状态。
下面是 Python 中使用 Tarjan 算法求解强连通分量的一个示例:
def tarjan(graph): index_counter = [0] stack = [] lowlink = {} index = {} result = [] def strongconnect(node): nonlocal index_counter lowlink[node] = index[node] = index_counter[0] index_counter[0] += 1 stack.append(node) for child in graph[node]: if child not in index: strongconnect(child) lowlink[node] = min(lowlink[node], lowlink[child]) elif child in stack: lowlink[node] = min(lowlink[node], index[child]) if lowlink[node] == index[node]: connected_component = [] while True: topnode = stack.pop() connected_component.append(topnode) if topnode == node: break result.append(connected_component) for node in graph: if node not in index: strongconnect(node) return result
其中,参数 graph 表示输入的有向图,要求为字典形式,其中键表示节点名称(可以是字符串),值表示与该节点直接相邻的节点列表(也可以是字符串)。
以下为使用该算法求解范例:
example_graph = { 'a': ['b'], 'b': ['c', 'd'], 'c': ['a', 'e'], 'd': ['e', 'g'], 'e': ['d'], 'f': ['d', 'g'], 'g': [] } print(tarjan(example_graph))
输出结果为:
[['c', 'b', 'a'], ['e', 'd'], ['g'], ['f']]
其中,每个子列表都是一个强连通分量。对于本例子中的输入图,共有 4 个强连通分量。
相关文章