Source code for easygraph.functions.components.connected
from easygraph.utils.decorators import *
__all__ = [
"is_connected",
"number_connected_components",
"connected_components",
"connected_components_directed",
"connected_component_of_node",
]
[docs]@not_implemented_for("multigraph")
def is_connected(G):
"""Returns whether the graph is connected or not.
Parameters
----------
G : easygraph.Graph or easygraph.DiGraph
Returns
-------
is_biconnected : boolean
`True` if the graph is connected.
Examples
--------
>>> is_connected(G)
"""
assert len(G) != 0, "No node in the graph."
arbitrary_node = next(iter(G)) # Pick an arbitrary node to run BFS
return len(G) == sum(1 for node in _plain_bfs(G, arbitrary_node))
[docs]@not_implemented_for("multigraph")
def number_connected_components(G):
"""Returns the number of connected components.
Parameters
----------
G : easygraph.Graph
Returns
-------
number_connected_components : int
The number of connected components.
Examples
--------
>>> number_connected_components(G)
"""
return sum(1 for component in _generator_connected_components(G))
[docs]@not_implemented_for("multigraph")
@hybrid("cpp_connected_components_undirected")
def connected_components(G):
"""Returns a list of connected components, each of which denotes the edges set of a connected component.
Parameters
----------
G : easygraph.Graph
Returns
-------
connected_components : list of list
Each element list is the edges set of a connected component.
Examples
--------
>>> connected_components(G)
"""
seen = set()
for v in G:
if v not in seen:
c = set(_plain_bfs(G, v))
seen.update(c)
yield c
[docs]@not_implemented_for("multigraph")
@hybrid("cpp_connected_components_directed")
def connected_components_directed(G):
"""Returns a list of connected components, each of which denotes the edges set of a connected component.
Parameters
----------
G : easygraph.DiGraph
Returns
-------
connected_components : list of list
Each element list is the edges set of a connected component.
Examples
--------
>>> connected_components(G)
"""
seen = set()
for v in G:
if v not in seen:
c = set(_plain_bfs(G, v))
seen.update(c)
yield c
def _generator_connected_components(G):
seen = set()
for v in G:
if v not in seen:
component = set(_plain_bfs(G, v))
yield component
seen.update(component)
[docs]@not_implemented_for("multigraph")
def connected_component_of_node(G, node):
"""Returns the connected component that *node* belongs to.
Parameters
----------
G : easygraph.Graph
node : object
The target node
Returns
-------
connected_component_of_node : set
The connected component that *node* belongs to.
Examples
--------
Returns the connected component of one node `Jack`.
>>> connected_component_of_node(G, node='Jack')
"""
return set(_plain_bfs(G, node))
@hybrid("cpp_plain_bfs")
def _plain_bfs(G, source):
"""
A fast BFS node generator
"""
G_adj = G.adj
seen = set()
nextlevel = {source}
while nextlevel:
thislevel = nextlevel
nextlevel = set()
for v in thislevel:
if v not in seen:
yield v
seen.add(v)
nextlevel.update(G_adj[v])