Mini Shell
"""Implements finding connected components."""
from collections import deque
from ..helpers import make_subgraph
def get_connected_components(graph):
"""Finds all connected components of the graph.
Returns a list of lists, each containing the nodes that form a connected component.
Returns an empty list for an empty graph.
"""
list_of_components = []
component = [] # Not strictly necessary due to the while loop structure, but it helps the automated analysis tools
# Store a list of all unreached vertices
unreached = set(graph.get_all_node_ids())
to_explore = deque()
while len(unreached) > 0:
# This happens when we reach the end of a connected component and still have more vertices to search through
if len(to_explore) == 0:
n = unreached.pop()
unreached.add(n)
to_explore.append(n)
component = []
list_of_components.append(component)
# This is the BFS that searches for connected vertices
while len(to_explore) > 0:
n = to_explore.pop()
if n in unreached:
component.append(n)
unreached.remove(n)
nodes = graph.neighbors(n)
for n in nodes:
if n in unreached:
to_explore.append(n)
return list_of_components
def get_connected_components_as_subgraphs(graph):
"""Finds all connected components of the graph.
Returns a list of graph objects, each representing a connected component.
Returns an empty list for an empty graph.
"""
components = get_connected_components(graph)
list_of_graphs = []
for c in components:
edge_ids = set()
nodes = [graph.get_node(node) for node in c]
for n in nodes:
# --Loop through the edges in each node, to determine if it should be included
for e in n['edges']:
# --Only add the edge to the subgraph if both ends are in the subgraph
edge = graph.get_edge(e)
a, b = edge['vertices']
if a in c and b in c:
edge_ids.add(e)
# --Build the subgraph and add it to the list
list_of_edges = list(edge_ids)
subgraph = make_subgraph(graph, c, list_of_edges)
list_of_graphs.append(subgraph)
return list_of_graphs
Zerion Mini Shell 1.0