Python中使用DFS判断图(Graph)是否为DAG(Directed Acyclic Graph)
以下是使用DFS判断图是否为DAG的Python代码演示:
def is_dag(graph): """ 判断有向图是否为DAG :param graph: 有向图 :return: True表示是DAG,False表示不是DAG """ visited = set() # 记录已访问过的节点 stack = set() # 记录在当前DFS路径中的节点 for node in graph: if node not in visited: if dfs(node, visited, stack, graph): return False return True def dfs(node, visited, stack, graph): """ 深度优先搜索 :param node: 当前搜索的节点 :param visited: 已访问过的节点集合 :param stack: 在当前DFS路径中的节点集合 :param graph: 图 :return: True表示存在环,False表示不存在环 """ visited.add(node) stack.add(node) for neighbor in graph[node]: if neighbor not in visited: if dfs(neighbor, visited, stack, graph): return True elif neighbor in stack: return True stack.remove(node) return False # 示例 graph1 = { 'a': ['b', 'c'], 'b': ['c', 'd'], 'c': [], 'd': ['a'] } print(is_dag(graph1)) # False:存在环a->b->d->a graph2 = { 1: [2, 3], 2: [4, 5], 3: [5], 4: [], 5: [] } print(is_dag(graph2)) # True:无环 graph3 = { 'pidan': ['code', 'programming'], 'code': ['python'], 'programming': [] } print(is_dag(graph3)) # True:无环
在上述示例代码中,函数is_dag()
接收一个有向图作为参数,使用一个visited
集合记录已访问过的节点,使用一个stack
集合记录在当前DFS路径中的节点。然后对于每个未被访问过的节点,调用dfs()
函数进行深度优先搜索。
函数dfs()
接收当前搜索的节点node
、已访问过的节点集合visited
、在当前DFS路径中的节点集合stack
和整个图graph
作为参数。函数先将当前节点加入visited
和stack
中,然后遍历当前节点的所有邻居节点。如果某个邻居节点还未被访问过,则递归调用dfs()
函数;如果某个邻居节点已经在当前DFS路径中,则说明存在环,返回True。最后将当前节点从stack
中删除,表示已经结束在该节点的DFS路径,返回False。
在示例中,演示了三个图:graph1
存在环,graph2
为DAG,graph3
为DAG。对这三个图分别调用is_dag()
函数,可以验证结果是否符合预期。
相关文章