我有一个列表列表,每个列表都是一个节点,并且包含其他节点的边缘。例如
[[1, 1, 0], [1, 1, 0], [0, 0, 1]]
该节点在引用其自身位置时以及在其与另一个节点的边缘时,具有1
;在不存在边缘时,其具有0
。
这意味着node 0
([1, 1, 0]
)已连接到node 1
,而node 2
([0,0,1]
)未连接到任何其他节点。因此,可以将以下列表视为邻接矩阵:
1 1 0 <- node 0
1 1 0 <- node 1
0 0 1 <- node 2
此外,节点是否与另一个节点连接是可传递的,这意味着如果node 1
连接到node 2
且node 2
连接到node 3
,则节点1
和3
也被连接(通过传递性)。
考虑到所有这些因素,我希望能够知道矩阵中有多少个相连的组。我应该使用哪种算法,递归DFS?有人可以提供有关如何解决此问题的任何提示或伪代码吗?
答案 0 :(得分:2)
如果输入矩阵保证可以描述 transitive 连通性,则它具有特殊的形式,允许算法仅探测矩阵元素的一个子集。这是Python中的示例实现:
def count_connected_groups(adj):
n = len(adj)
nodes_to_check = set([i for i in range(n)]) # [] not needed in python 3
count = 0
while nodes_to_check:
count += 1
node = nodes_to_check.pop()
adjacent = adj[node]
other_group_members = set()
for i in nodes_to_check:
if adjacent[i]:
other_group_members.add(i)
nodes_to_check -= other_group_members
return count
# your example:
adj_0 = [[1, 1, 0], [1, 1, 0], [0, 0, 1]]
# same with tuples and booleans:
adj_1 = ((True, True, False), (True, True, False), (False, False, True))
# another connectivity matrix:
adj_2 = ((1, 1, 1, 0, 0),
(1, 1, 1, 0, 0),
(1, 1, 1, 0, 0),
(0, 0, 0, 1, 1),
(0, 0, 0, 1, 1))
# and yet another:
adj_3 = ((1, 0, 1, 0, 0),
(0, 1, 0, 1, 0),
(1, 0, 1, 0, 0),
(0, 1, 0, 1, 0),
(0, 0, 0, 0, 1))
for a in adj_0, adj_1, adj_2, adj_3:
print(a)
print(count_connected_groups(a))
# [[1, 1, 0], [1, 1, 0], [0, 0, 1]]
# 2
# ((True, True, False), (True, True, False), (False, False, True))
# 2
# ((1, 1, 1, 0, 0), (1, 1, 1, 0, 0), (1, 1, 1, 0, 0), (0, 0, 0, 1, 1), (0, 0, 0, 1, 1))
# 2
# ((1, 0, 1, 0, 0), (0, 1, 0, 1, 0), (1, 0, 1, 0, 0), (0, 1, 0, 1, 0), (0, 0, 0, 0, 1))
# 3
同一算法的优化版本(可读性较低,但更快,更容易翻译成其他语言)如下:
def count_connected_groups(adj):
n = len(adj)
nodes_to_check = [i for i in range(n)] # [0, 1, ..., n-1]
count = 0
while n:
count += 1
n -= 1; node = nodes_to_check[n]
adjacent = adj[node]
i = 0
while i < n:
other_node = nodes_to_check[i]
if adjacent[other_node]:
n -= 1; nodes_to_check[i] = nodes_to_check[n]
else:
i += 1
return count
答案 1 :(得分:1)
有很多方法可以做到这一点。您可以使用DFS / BFS或不交集来解决此问题。以下是一些有用的链接:
https://www.geeksforgeeks.org/connected-components-in-an-undirected-graph/ https://www.geeksforgeeks.org/find-the-number-of-islands-set-2-using-disjoint-set/