U
    ¹mœd  ã                   @   sb   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	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Úcuthill_mckee_orderingÚreverse_cuthill_mckee_orderingc                 c   s*   t  | ¡D ]}t|  |¡|ƒE dH  q
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)

    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 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© r   úK/home/sam/Atlas/atlas_env/lib/python3.8/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)

    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 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   G   s    5c                 c   s†   |d krt | ƒ}n|| ƒ}|h}t|gƒ}|r‚| ¡ }|V  t|  t| | ƒ| ¡tdƒd�}dd„ |D ƒ}| |¡ | |¡ q*d S )Né   ©Úkeyc                 S   s   g | ]\}}|‘qS r   r   )Ú.0ÚnÚdr   r   r   Ú
<listcomp>‹   s     z4connected_cuthill_mckee_ordering.<locals>.<listcomp>)	Úpseudo_peripheral_noder   ÚpopleftÚsortedÚdegreeÚsetr   ÚupdateÚextend)r
   r   ÚstartÚvisitedÚqueueÚparentÚndÚchildrenr   r   r   r	      s    

"
r	   c                    sp   t | ƒ}d}|}tt | |¡ƒ}t| ¡ ƒ‰ ˆ |kr6qlˆ }‡ fdd„| ¡ D ƒ}t|  |¡t	dƒd�\}}q|S )Nr   c                 3   s   | ]\}}|ˆ kr|V  qd S )Nr   )r   r   Ú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farthestÚdegr   r&   r   r   �   s    r   )N)N)N)Ú__doc__Úcollectionsr   Úoperatorr   Znetworkxr   Úutilsr   Ú__all__r   r   r	   r   r   r   r   r   Ú<module>   s   
9
8
