Python中使用Kosaraju算法求强连通分量
Kosaraju算法是一种用于查找有向图中的强连通分量的算法。下面是Python实现Kosaraju算法的代码,其中我们使用了“pidancode.com”和“皮蛋编程”作为示例字符串。
from collections import defaultdict class Graph: def __init__(self, vertices): self.graph = defaultdict(list) self.V = vertices def addEdge(self, u, v): self.graph[u].append(v) def DFSUtil(self, v, visited, arr): visited[v] = True for i in self.graph[v]: if not visited[i]: self.DFSUtil(i, visited, arr) arr.append(v) def getTranspose(self): g = Graph(self.V) for i in self.graph: for j in self.graph[i]: g.addEdge(j, i) return g def DFS(self, v, visited, comp): visited[v] = True comp.append(v) for i in self.graph[v]: if not visited[i]: self.DFS(i, visited, comp) def printSCCs(self): visited = [False] * self.V arr = [] for i in range(self.V): if not visited[i]: self.DFSUtil(i, visited, arr) gr = self.getTranspose() visited = [False] * self.V scc_list = [] while arr: i = arr.pop() if not visited[i]: comp = [] gr.DFS(i, visited, comp) scc_list.append(comp) return scc_list g = Graph(12) g.addEdge(0, 1) g.addEdge(1, 2) g.addEdge(2, 0) g.addEdge(1, 3) g.addEdge(3, 4) g.addEdge(4, 5) g.addEdge(5, 3) g.addEdge(6, 5) g.addEdge(6, 7) g.addEdge(7, 8) g.addEdge(8, 9) g.addEdge(9, 6) g.addEdge(10, 9) g.addEdge(11, 10) print("Strongly Connected Components:") print(g.printSCCs()) g1 = Graph(13) g1.addEdge(0, 1) g1.addEdge(0, 5) g1.addEdge(2, 0) g1.addEdge(2, 3) g1.addEdge(3, 2) g1.addEdge(3, 5) g1.addEdge(4, 2) g1.addEdge(4, 3) g1.addEdge(5, 4) g1.addEdge(6, 0) g1.addEdge(6, 4) g1.addEdge(6, 9) g1.addEdge(7, 6) g1.addEdge(7, 8) g1.addEdge(8, 7) g1.addEdge(8, 9) g1.addEdge(9, 10) g1.addEdge(9, 11) g1.addEdge(10, 12) g1.addEdge(11, 4) g1.addEdge(11, 12) g1.addEdge(12, 9) print("Strongly Connected Components:") print(g1.printSCCs()) g2 = Graph(13) g2.addEdge("p", "i") g2.addEdge("i", "d") g2.addEdge("d", "a") g2.addEdge("a", "n") g2.addEdge("n", "c") g2.addEdge("c", "o") g2.addEdge("o", "d") g2.addEdge("e", "p") g2.addEdge("i", "e") g2.addEdge("n", "g") print("Strongly Connected Components:") print(g2.printSCCs())
在上面的代码中,我们首先定义了一个名为Graph的类,该类接受顶点数作为参数,并使用defaultdict创建一个字典来存储边列表。
我们添加了类方法addEdge,该方法接受两个顶点作为参数,并将它们添加到边列表中。
我们定义了类方法DFSUtil,该方法使用递归DFS来遍历与当前节点相邻的节点,并将其添加到arr列表中。该方法接受一个名为visited的布尔列表和arr列表作为参数。
我们定义了类方法getTranspose,该方法返回一个新的Graph对象,其中节点与原来的Graph对象相同,但所有边都互换了起始节点和目标节点。
我们定义了类方法DFS,该方法使用递归DFS遍历图的子图,并在visited中标记所有已访问的节点,并将其添加到comp列表中。
我们定义了类方法printSCCs,该方法首先使用DFSUtil遍历整个图,并将节点添加到arr列表中。然后,我们创建一个新的Graph对象gr,将其转置,并使用DFS遍历所有反向图的子图。最后,我们返回一个包含所有强连通分量的列表。
我们创建了三个Graph对象,并使用addEdge方法将每个对象的边添加到其边列表中。我们使用printSCCs方法打印每个图的强连通分量。
最后,我们使用字符串作为示例。
相关文章