
    wg                         d Z ddlmZ ddlZddgZ ej                  ddid      dd	       Zej                  dd
       Zy)aY  Routines to find the boundary of a set of nodes.

An edge boundary is a set of edges, each of which has exactly one
endpoint in a given set of nodes (or, in the case of directed graphs,
the set of edges whose source node is in the set).

A node boundary of a set *S* of nodes is the set of (out-)neighbors of
nodes in *S* that are outside *S*.

    )chainNedge_boundarynode_boundarydatadefault)
edge_attrspreserve_edge_attrsc                    	 |D ch c]	  }|| v s| c}| j                         r| j                  |||      }n| j                  ||      }|fd|D        S t        |      		fd|D        S c c}w )a  Returns the edge boundary of `nbunch1`.

    The *edge boundary* of a set *S* with respect to a set *T* is the
    set of edges (*u*, *v*) such that *u* is in *S* and *v* is in *T*.
    If *T* is not specified, it is assumed to be the set of all nodes
    not in *S*.

    Parameters
    ----------
    G : NetworkX graph

    nbunch1 : iterable
        Iterable of nodes in the graph representing the set of nodes
        whose edge boundary will be returned. (This is the set *S* from
        the definition above.)

    nbunch2 : iterable
        Iterable of nodes representing the target (or "exterior") set of
        nodes. (This is the set *T* from the definition above.) If not
        specified, this is assumed to be the set of all nodes in `G`
        not in `nbunch1`.

    keys : bool
        This parameter has the same meaning as in
        :meth:`MultiGraph.edges`.

    data : bool or object
        This parameter has the same meaning as in
        :meth:`MultiGraph.edges`.

    default : object
        This parameter has the same meaning as in
        :meth:`MultiGraph.edges`.

    Returns
    -------
    iterator
        An iterator over the edges in the boundary of `nbunch1` with
        respect to `nbunch2`. If `keys`, `data`, or `default`
        are specified and `G` is a multigraph, then edges are returned
        with keys and/or data, as in :meth:`MultiGraph.edges`.

    Examples
    --------
    >>> G = nx.wheel_graph(6)

    When nbunch2=None:

    >>> list(nx.edge_boundary(G, (1, 3)))
    [(1, 0), (1, 2), (1, 5), (3, 0), (3, 2), (3, 4)]

    When nbunch2 is given:

    >>> list(nx.edge_boundary(G, (1, 3), (2, 0)))
    [(1, 0), (1, 2), (3, 0), (3, 2)]

    Notes
    -----
    Any element of `nbunch` that is not in the graph `G` will be
    ignored.

    `nbunch1` and `nbunch2` are usually meant to be disjoint, but in
    the interest of speed and generality, that is not required here.

    )r   keysr   )r   r   c              3   B   K   | ]  }|d    v |d   v z  s|  ywr      N ).0enset1s     a/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/algorithms/boundary.py	<genexpr>z edge_boundary.<locals>.<genexpr>e   s(     FaQqTU]qtu}$EFs   c              3   Z   K   | ]"  }|d    v r|d   v s|d   v r|d    v r| $ ywr   r   )r   r   r   nset2s     r   r   z edge_boundary.<locals>.<genexpr>g   sB      aDEMadem11Q45= 	
s   (+)is_multigraphedgesset)
Gnbunch1nbunch2r   r   r   nr   r   r   s
           @@r   r   r      s    F  *116Q*E 	DtWED':
 F5FFLE # +s
   	A6A6c                      |D ch c]	  }| v s| }}t        t        j                   fd|D                    |z
  }||t        |      z  }|S c c}w )ac  Returns the node boundary of `nbunch1`.

    The *node boundary* of a set *S* with respect to a set *T* is the
    set of nodes *v* in *T* such that for some *u* in *S*, there is an
    edge joining *u* to *v*. If *T* is not specified, it is assumed to
    be the set of all nodes not in *S*.

    Parameters
    ----------
    G : NetworkX graph

    nbunch1 : iterable
        Iterable of nodes in the graph representing the set of nodes
        whose node boundary will be returned. (This is the set *S* from
        the definition above.)

    nbunch2 : iterable
        Iterable of nodes representing the target (or "exterior") set of
        nodes. (This is the set *T* from the definition above.) If not
        specified, this is assumed to be the set of all nodes in `G`
        not in `nbunch1`.

    Returns
    -------
    set
        The node boundary of `nbunch1` with respect to `nbunch2`.

    Examples
    --------
    >>> G = nx.wheel_graph(6)

    When nbunch2=None:

    >>> list(nx.node_boundary(G, (3, 4)))
    [0, 2, 5]

    When nbunch2 is given:

    >>> list(nx.node_boundary(G, (3, 4), (0, 1, 5)))
    [0, 5]

    Notes
    -----
    Any element of `nbunch` that is not in the graph `G` will be
    ignored.

    `nbunch1` and `nbunch2` are usually meant to be disjoint, but in
    the interest of speed and generality, that is not required here.

    c              3   (   K   | ]	  }|     y wNr   )r   vr   s     r   r   z node_boundary.<locals>.<genexpr>   s     !61!A$!6s   )r   r   from_iterable)r   r   r   r   r   bdys   `     r   r   r   n   s_    h  *116Q*E*
e!!!6!66
7%
?C s7|J +s
   	AA)NFFNr    )	__doc__	itertoolsr   networkxnx__all___dispatchabler   r   r       r   <module>r+      sb   	  O
, fi0fMW NWt 9 9r*   