o
    h                     @   s   d Z ddlmZ ddlZddlmZ g dZedejdddZ	edejdd	d
Z
ededejdddddZdS )zBridge-finding algorithms.    )chainN)not_implemented_for)bridgeshas_bridgeslocal_bridgesdirectedc                 c   s    |   }|rt| n| }tj||d}tt|}|dur+|t||	 }|
 D ]"\}}||f|vrQ||f|vrQ|rLt| | | dkrLq/||fV  q/dS )a@  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. Bridges are also known as cut-edges,
    isthmuses, or cut arcs.

    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`.

    NetworkXNotImplemented
        If `G` is a directed graph.

    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.

    The algorithm described in [1]_ requires a simple graph. If the provided
    graph is a multigraph, we convert it to a simple graph and verify that any
    bridges discovered by the chain decomposition algorithm are not multi-edges.

    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
    rootN   )is_multigraphnxGraphchain_decompositionsetr   from_iterablesubgraphnode_connected_componentcopyedgeslen)Gr	   
multigraphHchainschain_edgesuv r   o/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/networkx/algorithms/bridges.pyr      s   ;
r   c                 C   s,   zt t| |d W dS  ty   Y dS w )a  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`.

    NetworkXNotImplemented
        If `G` is a directed graph.

    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.

    r   FT)nextr   StopIteration)r   r	   r   r   r   r   S   s   4r   r   weight)
edge_attrsTc              	   #   s    |dur | j D ]\}}t| | t| | @ s||fV  qdS tj| || j D ]?\}}t| | t| | @ si||h  fdd}ztj| |||d}|||fV  W q* tjyh   ||tdfV  Y q*w q*dS )al  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`.

    Raises
    ------
    NetworkXNotImplemented
        If `G` is a directed graph or multigraph.

    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
    Tc                    s    |  vs| vr| ||S d S Nr   )nnbrdenodeswtr   r   	hide_edge   s   z local_bridges.<locals>.hide_edge)r!   infN)r   r   r   weighted_weight_functionshortest_path_lengthNetworkXNoPathfloat)r   	with_spanr!   r   r   r*   spanr   r'   r   r      s(   +
r   r#   )TN)__doc__	itertoolsr   networkxr   networkx.utilsr   __all___dispatchabler   r   r   r   r   r   r   <module>   s    F:
