Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
181
venv/Lib/site-packages/networkx/algorithms/bridges.py
Normal file
181
venv/Lib/site-packages/networkx/algorithms/bridges.py
Normal file
|
@ -0,0 +1,181 @@
|
|||
"""Bridge-finding algorithms."""
|
||||
from itertools import chain
|
||||
|
||||
import networkx as nx
|
||||
from networkx.utils import not_implemented_for
|
||||
|
||||
__all__ = ["bridges", "has_bridges", "local_bridges"]
|
||||
|
||||
|
||||
@not_implemented_for("multigraph")
|
||||
@not_implemented_for("directed")
|
||||
def bridges(G, root=None):
|
||||
"""Generate all bridges in a graph.
|
||||
|
||||
A *bridge* in a graph is an edge whose removal causes the number of
|
||||
connected components of the graph to increase. Equivalently, a bridge is an
|
||||
edge that does not belong to any cycle.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : undirected graph
|
||||
|
||||
root : node (optional)
|
||||
A node in the graph `G`. If specified, only the bridges in the
|
||||
connected component containing this node will be returned.
|
||||
|
||||
Yields
|
||||
------
|
||||
e : edge
|
||||
An edge in the graph whose removal disconnects the graph (or
|
||||
causes the number of connected components to increase).
|
||||
|
||||
Raises
|
||||
------
|
||||
NodeNotFound
|
||||
If `root` is not in the graph `G`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
The barbell graph with parameter zero has a single bridge:
|
||||
|
||||
>>> G = nx.barbell_graph(10, 0)
|
||||
>>> list(nx.bridges(G))
|
||||
[(9, 10)]
|
||||
|
||||
Notes
|
||||
-----
|
||||
This is an implementation of the algorithm described in _[1]. An edge is a
|
||||
bridge if and only if it is not contained in any chain. Chains are found
|
||||
using the :func:`networkx.chain_decomposition` function.
|
||||
|
||||
Ignoring polylogarithmic factors, the worst-case time complexity is the
|
||||
same as the :func:`networkx.chain_decomposition` function,
|
||||
$O(m + n)$, where $n$ is the number of nodes in the graph and $m$ is
|
||||
the number of edges.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] https://en.wikipedia.org/wiki/Bridge_%28graph_theory%29#Bridge-Finding_with_Chain_Decompositions
|
||||
"""
|
||||
chains = nx.chain_decomposition(G, root=root)
|
||||
chain_edges = set(chain.from_iterable(chains))
|
||||
for u, v in G.edges():
|
||||
if (u, v) not in chain_edges and (v, u) not in chain_edges:
|
||||
yield u, v
|
||||
|
||||
|
||||
@not_implemented_for("multigraph")
|
||||
@not_implemented_for("directed")
|
||||
def has_bridges(G, root=None):
|
||||
"""Decide whether a graph has any bridges.
|
||||
|
||||
A *bridge* in a graph is an edge whose removal causes the number of
|
||||
connected components of the graph to increase.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : undirected graph
|
||||
|
||||
root : node (optional)
|
||||
A node in the graph `G`. If specified, only the bridges in the
|
||||
connected component containing this node will be considered.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
Whether the graph (or the connected component containing `root`)
|
||||
has any bridges.
|
||||
|
||||
Raises
|
||||
------
|
||||
NodeNotFound
|
||||
If `root` is not in the graph `G`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
The barbell graph with parameter zero has a single bridge::
|
||||
|
||||
>>> G = nx.barbell_graph(10, 0)
|
||||
>>> nx.has_bridges(G)
|
||||
True
|
||||
|
||||
On the other hand, the cycle graph has no bridges::
|
||||
|
||||
>>> G = nx.cycle_graph(5)
|
||||
>>> nx.has_bridges(G)
|
||||
False
|
||||
|
||||
Notes
|
||||
-----
|
||||
This implementation uses the :func:`networkx.bridges` function, so
|
||||
it shares its worst-case time complexity, $O(m + n)$, ignoring
|
||||
polylogarithmic factors, where $n$ is the number of nodes in the
|
||||
graph and $m$ is the number of edges.
|
||||
|
||||
"""
|
||||
try:
|
||||
next(bridges(G))
|
||||
except StopIteration:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
@not_implemented_for("multigraph")
|
||||
@not_implemented_for("directed")
|
||||
def local_bridges(G, with_span=True, weight=None):
|
||||
"""Iterate over local bridges of `G` optionally computing the span
|
||||
|
||||
A *local bridge* is an edge whose endpoints have no common neighbors.
|
||||
That is, the edge is not part of a triangle in the graph.
|
||||
|
||||
The *span* of a *local bridge* is the shortest path length between
|
||||
the endpoints if the local bridge is removed.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : undirected graph
|
||||
|
||||
with_span : bool
|
||||
If True, yield a 3-tuple `(u, v, span)`
|
||||
|
||||
weight : function, string or None (default: None)
|
||||
If function, used to compute edge weights for the span.
|
||||
If string, the edge data attribute used in calculating span.
|
||||
If None, all edges have weight 1.
|
||||
|
||||
Yields
|
||||
------
|
||||
e : edge
|
||||
The local bridges as an edge 2-tuple of nodes `(u, v)` or
|
||||
as a 3-tuple `(u, v, span)` when `with_span is True`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
A cycle graph has every edge a local bridge with span N-1.
|
||||
|
||||
>>> G = nx.cycle_graph(9)
|
||||
>>> (0, 8, 8) in set(nx.local_bridges(G))
|
||||
True
|
||||
"""
|
||||
if with_span is not True:
|
||||
for u, v in G.edges:
|
||||
if not (set(G[u]) & set(G[v])):
|
||||
yield u, v
|
||||
else:
|
||||
wt = nx.weighted._weight_function(G, weight)
|
||||
for u, v in G.edges:
|
||||
if not (set(G[u]) & set(G[v])):
|
||||
enodes = {u, v}
|
||||
|
||||
def hide_edge(n, nbr, d):
|
||||
if n not in enodes or nbr not in enodes:
|
||||
return wt(n, nbr, d)
|
||||
return None
|
||||
|
||||
try:
|
||||
span = nx.shortest_path_length(G, u, v, weight=hide_edge)
|
||||
yield u, v, span
|
||||
except nx.NetworkXNoPath:
|
||||
yield u, v, float("inf")
|
Loading…
Add table
Add a link
Reference in a new issue