我有一个包含未知数量的不连通子图的图形。有什么好的算法(或Java库)可以找到它们全部吗?
我认为你所需要的通常被称为Flood Fill。你可以选择使用BFS或DFS遍历图。
基本上,你会选择一个未标记(也就是未着色)的节点并将一个新标签分配给它。然后,将相邻的所有节点分配相同的标签,并继续分配直到所有可达节点都被标记。
当没有更多的可达节点可以标记时,你需要选择另一个未标记的节点重复上述过程。需要注意的是,这个新节点未标记意味着它无法从先前的节点到达,因此它属于不同的不连通组件。
当没有更多未标记的节点时,你所使用的不同标签数目就是该图中组件的数量。每个节点的标签告诉你该节点属于哪个组件。
虽然不是Java实现,但或许对某些人有用。以下是在Python中实现的方法:
import networkx as nx
g = nx.Graph()
# add nodes/edges to graph
d = list(nx.connected_components(g))
# d contains disconnected subgraphs
# d[0] contains the biggest subgraph
更多信息 在这里。
尝试使用广度优先搜索来查找所有连接的节点?一旦您获得了连接节点的列表,您可以将该列表从所有节点的列表中减去。最终得到的是一个断开连接的节点列表。
For each edge A->B
If A is in a group and B is not, add B to group A
If A is not in a group and B is, add A to group B
If A and B are in different groups, merge the groups
If neither A or B is in a group, create new group containing A and B
伪代码:
graph = {nodes, edges}
groups = {}
foreach edge A->B in graph.edges:
groupA = findgroup(A)
groupB = findgroup(B)
if (groupA && !groupB)
groupA.add(B)
elif (!groupA && groupB)
groupB.add(A)
elif (groupA && groupB)
if (groupA != groupB)
groupA.union(groupB)
groups.delete(groupB)
else
groups.add({A,B})
findgroup(node):
for group in groups:
if group.contains(node):
return group
return null
foreach node in graph.nodes:
group = findgroup(node)
if !group:
groups.add({node})