ó
 ,µ[c           @   s‘   d  Z  d d l m Z d d l m Z d d l Z d d l m Z d j	 d g ƒ Z
 d	 d
 g Z d d „ Z d d „ Z d d „ Z d „  Z d S(   sB   
Cuthill-McKee ordering of graph nodes to produce sparse matrices
iÿÿÿÿ(   t   deque(   t
   itemgetterNi   (   t   arbitrary_elements   
s%   Aric Hagberg <aric.hagberg@gmail.com>t   cuthill_mckee_orderingt   reverse_cuthill_mckee_orderingc         c   sF   x? t  j |  ƒ D]. } x% t |  j | ƒ | ƒ D] } | Vq/ Wq Wd S(   sò  Generate an ordering (permutation) of the graph nodes to make
    a sparse matrix.

    Uses the Cuthill-McKee heuristic (based on breadth-first search) [1]_.

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

    heuristic : function, optional
      Function to choose starting node for RCM algorithm.  If None
      a node from a pseudo-peripheral pair is used.  A user-defined function
      can be supplied that takes a graph object and returns a single node.

    Returns
    -------
    nodes : generator
       Generator of nodes in Cuthill-McKee ordering.

    Examples
    --------
    >>> from networkx.utils import cuthill_mckee_ordering
    >>> G = nx.path_graph(4)
    >>> rcm = list(cuthill_mckee_ordering(G))
    >>> A = nx.adjacency_matrix(G, nodelist=rcm) # doctest: +SKIP

    Smallest degree node as heuristic function:

    >>> def smallest_degree(G):
    ...     return min(G, key=G.degree)
    >>> rcm = list(cuthill_mckee_ordering(G, heuristic=smallest_degree))


    See Also
    --------
    reverse_cuthill_mckee_ordering

    Notes
    -----
    The optimal solution the the bandwidth reduction is NP-complete [2]_.


    References
    ----------
    .. [1] E. Cuthill and J. McKee.
       Reducing the bandwidth of sparse symmetric matrices,
       In Proc. 24th Nat. Conf. ACM, pages 157-172, 1969.
       http://doi.acm.org/10.1145/800195.805928
    .. [2]  Steven S. Skiena. 1997. The Algorithm Design Manual.
       Springer-Verlag New York, Inc., New York, NY, USA.
    N(   t   nxt   connected_componentst    connected_cuthill_mckee_orderingt   subgraph(   t   Gt	   heuristict   ct   n(    (    s1   lib/python2.7/site-packages/networkx/utils/rcm.pyR      s    5c         C   s   t  t t |  d | ƒƒ ƒ S(   s  Generate an ordering (permutation) of the graph nodes to make
    a sparse matrix.

    Uses the reverse Cuthill-McKee heuristic (based on breadth-first search)
    [1]_.

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

    heuristic : function, optional
      Function to choose starting node for RCM algorithm.  If None
      a node from a pseudo-peripheral pair is used.  A user-defined function
      can be supplied that takes a graph object and returns a single node.

    Returns
    -------
    nodes : generator
       Generator of nodes in reverse Cuthill-McKee ordering.

    Examples
    --------
    >>> from networkx.utils import reverse_cuthill_mckee_ordering
    >>> G = nx.path_graph(4)
    >>> rcm = list(reverse_cuthill_mckee_ordering(G))
    >>> A = nx.adjacency_matrix(G, nodelist=rcm) # doctest: +SKIP

    Smallest degree node as heuristic function:

    >>> def smallest_degree(G):
    ...     return min(G, key=G.degree)
    >>> rcm = list(reverse_cuthill_mckee_ordering(G, heuristic=smallest_degree))


    See Also
    --------
    cuthill_mckee_ordering

    Notes
    -----
    The optimal solution the the bandwidth reduction is NP-complete [2]_.

    References
    ----------
    .. [1] E. Cuthill and J. McKee.
       Reducing the bandwidth of sparse symmetric matrices,
       In Proc. 24th Nat. Conf. ACM, pages 157-72, 1969.
       http://doi.acm.org/10.1145/800195.805928
    .. [2]  Steven S. Skiena. 1997. The Algorithm Design Manual.
       Springer-Verlag New York, Inc., New York, NY, USA.
    R
   (   t   reversedt   listR   (   R	   R
   (    (    s1   lib/python2.7/site-packages/networkx/utils/rcm.pyR   M   s    5c   
      c   sÏ   | d  k r t |  ƒ } n | |  ƒ } | h } t | g ƒ } x‰ | rÊ | j ƒ  } | Vt t |  j t |  | ƒ | ƒ ƒ d t d ƒ ƒ} g  | D] \ } } | ^ q• }	 | j	 |	 ƒ | j
 |	 ƒ qB Wd  S(   Nt   keyi   (   t   Nonet   pseudo_peripheral_nodeR    t   popleftt   sortedR   t   degreet   setR   t   updatet   extend(
   R	   R
   t   startt   visitedt   queuet   parentt   ndR   t   dt   children(    (    s1   lib/python2.7/site-packages/networkx/utils/rcm.pyR   …   s    		&c            s¬   t  |  ƒ } d } | } x t r§ t t j |  | ƒ ƒ } t | j ƒ  ƒ ‰  ˆ  | k r[ Pn  ˆ  } ‡  f d †  | j ƒ  Dƒ } t |  j	 | ƒ d t
 d ƒ ƒ\ } } q W| S(   Ni    c         3   s'   |  ] \ } } | ˆ  k r | Vq d  S(   N(    (   t   .0R   t   dist(   t   l(    s1   lib/python2.7/site-packages/networkx/utils/rcm.pys	   <genexpr>£   s    R   i   (   R   t   Truet   dictR   t   shortest_path_lengtht   maxt   valuest   itemst   minR   R   (   R	   t   ut   lpt   vt   splt   farthestt   deg(    (   R!   s1   lib/python2.7/site-packages/networkx/utils/rcm.pyR   —   s    	+(   t   __doc__t   collectionsR    t   operatorR   t   networkxR   t   utilsR   t   joint
   __author__t   __all__R   R   R   R   R   (    (    (    s1   lib/python2.7/site-packages/networkx/utils/rcm.pyt   <module>   s   	:8