我正在尝试将所有连接的组件放入图表中并将其打印出来。我将浏览图形的每个节点,并从该节点开始执行深度优先搜索(DFS)。这是我的代码:
graph = {
'a': ['b'],
'b': ['c'],
'c': ['d'],
'd': [],
'e': ['f'],
'f': []
}
def DFS(graph, start_node, stack = [], visited = []):
stack.append(start_node)
while stack:
v = stack.pop()
if v not in visited:
visited.append(v)
for neighbor in graph[v]:
stack.append(neighbor)
return visited
def dfs_get_connected_components_util(graph):
visited = []
for node in graph:
if node not in visited:
DFS_algo = DFS(graph, node)
print(DFS_algo)
visited = DFS_algo
print(dfs_get_connected_components_util(graph))
根据我的图表,有两个连接的组件,a - > b - > c - > d 和e - > ˚F
相反,我得到以下打印输出:
['c', 'd']
['c', 'd', 'a', 'b']
['c', 'd', 'a', 'b', 'f']
['c', 'd', 'a', 'b', 'f', 'e']
我似乎无法弄清楚我在连接组件功能中做错了什么。我想这可能更像是一个蟒蛇问题。
答案 0 :(得分:1)
这就是我想出来的。 我在内联添加了一些注释来解释我的所作所为。 为了清晰起见,有些东西被转移到全球。我通常不建议使用全局变量。
关键是理解递归,并记住在分配对象(不是文字)时,只分配引用,不它的副本。
请注意,此解决方案假设图表无向。请在下面的注释部分查看更多详细信息。
随意要求澄清。
from collections import defaultdict
graph = {
'a': ['b'],
'b': ['c'],
'c': ['d'],
'd': [],
'e': ['f'],
'f': []
}
connected_components = defaultdict(set)
def dfs(node):
"""
The key is understanding the recursion
The recursive assumption is:
After calling `dfs(node)`, the `connected_components` dict contains all the connected as keys,
and the values are *the same set* that contains all the connected nodes.
"""
global connected_components, graph
if node not in connected_components:
# this is important, so neighbors won't try to traverse current node
connected_components[node] = set()
for next_ in graph[node]:
dfs(next_)
# according the recursive assumption, connected_component of `next_` is also the one of `node`
connected_components[node] = connected_components[next_]
# all that's left is add the current node
connected_components[node].add(node)
for node_ in graph:
dfs(node_)
# get all connected components and convert to tuples, so they are hashable
connected_comp_as_tuples = map(tuple, connected_components.values())
# use ``set`` to make the list of connected components distinct (without repetition)
unique_components = set(connected_comp_as_tuples)
print(unique_components)
set
,即使我们确实不需要一个节点(当节点有邻居时,该集合是冗余的并且将被覆盖)。