ó
 ,ľ[c           @   s˝   d  Z  d d l m Z d d l m Z d d l Z d d d d d	 d
 d d g Z d d d  Z	 d d  Z
 d d d  Z d d d  Z d d d  Z d d d  Z d   Z d   Z d S(   s7   Functions for finding and evaluating cuts in a graph.

i˙˙˙˙(   t   division(   t   chainNt   boundary_expansiont   conductancet   cut_sizet   edge_expansiont   mixing_expansiont   node_expansiont   normalized_cut_sizet   volumec      
   C   sn   t  j |  | | d | d d } |  j   rZ t | t  j |  | | d | d d  } n  t d   | D  S(   sŠ  Returns the size of the cut between two sets of nodes.

    A *cut* is a partition of the nodes of a graph into two sets. The
    *cut size* is the sum of the weights of the edges "between" the two
    sets of nodes.

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

    S : sequence
        A sequence of nodes in `G`.

    T : sequence
        A sequence of nodes in `G`. If not specified, this is taken to
        be the set complement of `S`.

    weight : object
        Edge attribute key to use as weight. If not specified, edges
        have weight one.

    Returns
    -------
    number
        Total weight of all edges from nodes in set `S` to nodes in
        set `T` (and, in the case of directed graphs, all edges from
        nodes in `T` to nodes in `S`).

    Examples
    --------
    In the graph with two cliques joined by a single edges, the natural
    bipartition of the graph into two blocks, one for each clique,
    yields a cut of weight one::

        >>> G = nx.barbell_graph(3, 0)
        >>> S = {0, 1, 2}
        >>> T = {3, 4, 5}
        >>> nx.cut_size(G, S, T)
        1

    Each parallel edge in a multigraph is counted when determining the
    cut size::

        >>> G = nx.MultiGraph(['ab', 'ab'])
        >>> S = {'a'}
        >>> T = {'b'}
        >>> nx.cut_size(G, S, T)
        2

    Notes
    -----
    In a multigraph, the cut size is the total weight of edges including
    multiplicity.

    t   datat   defaulti   c         s   s   |  ] \ } } } | Vq d  S(   N(    (   t   .0t   ut   vt   weight(    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pys	   <genexpr>W   s    (   t   nxt   edge_boundaryt   is_directedR   t   sum(   t   Gt   St   TR   t   edges(    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR      s    8!-c         C   s>   |  j    r |  j n |  j } t d   | | d | D  S(   sx  Returns the volume of a set of nodes.

    The *volume* of a set *S* is the sum of the (out-)degrees of nodes
    in *S* (taking into account parallel edges in multigraphs). [1]

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

    S : sequence
        A sequence of nodes in `G`.

    weight : object
        Edge attribute key to use as weight. If not specified, edges
        have weight one.

    Returns
    -------
    number
        The volume of the set of nodes represented by `S` in the graph
        `G`.

    See also
    --------
    conductance
    cut_size
    edge_expansion
    edge_boundary
    normalized_cut_size

    References
    ----------
    .. [1] David Gleich.
           *Hierarchical Directed Spectral Graph Partitioning*.
           <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf>

    c         s   s   |  ] \ } } | Vq d  S(   N(    (   R   R   t   d(    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pys	   <genexpr>   s    R   (   R   t
   out_degreet   degreeR   (   R   R   R   R   (    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR	   Z   s    &c         C   s~   | d k r% t |   t |  } n  t |  | d | d | } t |  | d | } t |  | d | } | d | d | S(   sú  Returns the normalized size of the cut between two sets of nodes.

    The *normalized cut size* is the cut size times the sum of the
    reciprocal sizes of the volumes of the two sets. [1]

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

    S : sequence
        A sequence of nodes in `G`.

    T : sequence
        A sequence of nodes in `G`.

    weight : object
        Edge attribute key to use as weight. If not specified, edges
        have weight one.

    Returns
    -------
    number
        The normalized cut size between the two sets `S` and `T`.

    Notes
    -----
    In a multigraph, the cut size is the total weight of edges including
    multiplicity.

    See also
    --------
    conductance
    cut_size
    edge_expansion
    volume

    References
    ----------
    .. [1] David Gleich.
           *Hierarchical Directed Spectral Graph Partitioning*.
           <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf>

    R   R   i   N(   t   Nonet   setR   R	   (   R   R   R   R   t   num_cut_edgest   volume_St   volume_T(    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR      s    ,c         C   sx   | d k r% t |   t |  } n  t |  | | d | } t |  | d | } t |  | d | } | t | |  S(   sh  Returns the conductance of two sets of nodes.

    The *conductance* is the quotient of the cut size and the smaller of
    the volumes of the two sets. [1]

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

    S : sequence
        A sequence of nodes in `G`.

    T : sequence
        A sequence of nodes in `G`.

    weight : object
        Edge attribute key to use as weight. If not specified, edges
        have weight one.

    Returns
    -------
    number
        The conductance between the two sets `S` and `T`.

    See also
    --------
    cut_size
    edge_expansion
    normalized_cut_size
    volume

    References
    ----------
    .. [1] David Gleich.
           *Hierarchical Directed Spectral Graph Partitioning*.
           <https://www.cs.purdue.edu/homes/dgleich/publications/Gleich%202005%20-%20hierarchical%20directed%20spectral.pdf>

    R   N(   R   R   R   R	   t   min(   R   R   R   R   R   R   R   (    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR   ¸   s    'c         C   s]   | d k r% t |   t |  } n  t |  | d | d | } | t t |  t |   S(   sĄ  Returns the edge expansion between two node sets.

    The *edge expansion* is the quotient of the cut size and the smaller
    of the cardinalities of the two sets. [1]

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

    S : sequence
        A sequence of nodes in `G`.

    T : sequence
        A sequence of nodes in `G`.

    weight : object
        Edge attribute key to use as weight. If not specified, edges
        have weight one.

    Returns
    -------
    number
        The edge expansion between the two sets `S` and `T`.

    See also
    --------
    boundary_expansion
    mixing_expansion
    node_expansion

    References
    ----------
    .. [1] Fan Chung.
           *Spectral Graph Theory*.
           (CBMS Regional Conference Series in Mathematics, No. 92),
           American Mathematical Society, 1997, ISBN 0-8218-0315-8
           <http://www.math.ucsd.edu/~fan/research/revised.html>

    R   R   N(   R   R   R   R    t   len(   R   R   R   R   R   (    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR   ç   s    (c         C   s3   t  |  | d | d | } |  j   } | d | S(   sk  Returns the mixing expansion between two node sets.

    The *mixing expansion* is the quotient of the cut size and twice the
    number of edges in the graph. [1]

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

    S : sequence
        A sequence of nodes in `G`.

    T : sequence
        A sequence of nodes in `G`.

    weight : object
        Edge attribute key to use as weight. If not specified, edges
        have weight one.

    Returns
    -------
    number
        The mixing expansion between the two sets `S` and `T`.

    See also
    --------
    boundary_expansion
    edge_expansion
    node_expansion

    References
    ----------
    .. [1] Vadhan, Salil P.
           "Pseudorandomness."
           *Foundations and Trends
           in Theoretical Computer Science* 7.1â3 (2011): 1â336.
           <https://doi.org/10.1561/0400000010>

    R   R   i   (   R   t   number_of_edges(   R   R   R   R   R   t   num_total_edges(    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR     s    (c            s9   t  t j   f d   | D   } t |  t |  S(   s­  Returns the node expansion of the set `S`.

    The *node expansion* is the quotient of the size of the node
    boundary of *S* and the cardinality of *S*. [1]

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

    S : sequence
        A sequence of nodes in `G`.

    Returns
    -------
    number
        The node expansion of the set `S`.

    See also
    --------
    boundary_expansion
    edge_expansion
    mixing_expansion

    References
    ----------
    .. [1] Vadhan, Salil P.
           "Pseudorandomness."
           *Foundations and Trends
           in Theoretical Computer Science* 7.1â3 (2011): 1â336.
           <https://doi.org/10.1561/0400000010>

    c         3   s   |  ] }   j  |  Vq d  S(   N(   t	   neighbors(   R   R   (   R   (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pys	   <genexpr>e  s    (   R   R   t   from_iterableR!   (   R   R   t   neighborhood(    (   R   s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR   D  s    !%c         C   s    t  t j |  |   t  |  S(   sŽ  Returns the boundary expansion of the set `S`.

    The *boundary expansion* is the quotient of the size of the edge
    boundary and the cardinality of *S*. [1]

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

    S : sequence
        A sequence of nodes in `G`.

    Returns
    -------
    number
        The boundary expansion of the set `S`.

    See also
    --------
    edge_expansion
    mixing_expansion
    node_expansion

    References
    ----------
    .. [1] Vadhan, Salil P.
           "Pseudorandomness."
           *Foundations and Trends in Theoretical Computer Science*
           7.1â3 (2011): 1â336.
           <https://doi.org/10.1561/0400000010>

    (   R!   R   t   node_boundary(   R   R   (    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyR   k  s    !(   t   __doc__t
   __future__R    t	   itertoolsR   t   networkxR   t   __all__R   R   R	   R   R   R   R   R   R   (    (    (    s7   lib/python2.7/site-packages/networkx/algorithms/cuts.pyt   <module>   s   		>*4/./	'