B
    ,[-                 @   sn   d Z ddlmZ ddlmZ ddlZddlmZ d	dgZ
d	d
gZddd	Zddd
ZdddZdd ZdS )zB
Cuthill-McKee ordering of graph nodes to produce sparse matrices
    )deque)
itemgetterN   )arbitrary_element
z%Aric Hagberg <aric.hagberg@gmail.com>cuthill_mckee_orderingreverse_cuthill_mckee_orderingc             c   s8   x2t | D ]$}xt| ||D ]
}|V  q"W qW dS )a  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)nxZconnected_components connected_cuthill_mckee_orderingZsubgraph)G	heuristiccn r   1lib/python3.7/site-packages/networkx/utils/rcm.pyr      s    5c             C   s   t tt| |dS )a  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   )reversedlistr   )r   r   r   r   r   r   M   s    5c             c   s   |d krt | }n|| }|h}t|g}x^|r| }|V  tt| t| | | tdd}dd |D }|| |	| q,W d S )N   )keyc             S   s   g | ]\}}|qS r   r   ).0r   dr   r   r   
<listcomp>   s    z4connected_cuthill_mckee_ordering.<locals>.<listcomp>)
pseudo_peripheral_noder   popleftsortedr   degreesetr   updateextend)r   r   startZvisitedZqueueparentZndZchildrenr   r   r   r
      s    


r
   c                st   t | }d}|}x^tt| |}t|   |kr8P  } fdd| D }t| |t	dd\}}qW |S )Nr   c             3   s   | ]\}}| kr|V  qd S )Nr   )r   r   Zdist)lr   r   	<genexpr>   s    z)pseudo_peripheral_node.<locals>.<genexpr>r   )r   )
r   dictr	   Zshortest_path_lengthmaxvaluesitemsminr   r   )r   uZlpvZsplZfarthestZdegr   )r!   r   r      s    r   )N)N)N)__doc__collectionsr   operatorr   Znetworkxr	   Zutilsr   join
__author____all__r   r   r
   r   r   r   r   r   <module>   s   
:
8
