
    h                         S r SSKJr  SSKJr  SSKJr  SSKrSSK	J
r
  SSKJr  \
rS/r\" S	5      \R                  SS
 j5       5       rS rS rS rS rg)z,
Moody and White algorithm for k-components
    )defaultdict)combinations)
itemgetterN)edmonds_karp)not_implemented_fork_componentsdirectedc           	      t   [        [        5      nUc  [        n[        R                  " U 5       H3  n[        U5      n[        U5      S:  d  M  US   R                  U5        M5     [        R                  " U 5       Vs/ s H  oPR                  U5      PM     nnU H3  n[        U5      n[        U5      S:  d  M  US   R                  U5        M5     U GH0  n	[        U	5      S::  a  M  [        R                  " XS9n
U
S:  a  X*   R                  [        U	5      5        [        [        R                  " XUS95      nU
[        XU
5      4/nU(       d  M  US   u  p [        U5      nU	R                  U5      n[        R                  " UUS9nUU:  a#  US:  a  UU   R                  [        U5      5        [        [        R                  " UUUS95      nU(       a  UR                  U[        UUU5      45        U(       a  M  GM3     [!        U5      $ s  snf ! [         a    UR                  5          N:f = f)a/  Returns the k-component structure of a graph G.

A `k`-component is a maximal subgraph of a graph G that has, at least,
node connectivity `k`: we need to remove at least `k` nodes to break it
into more components. `k`-components have an inherent hierarchical
structure because they are nested in terms of connectivity: a connected
graph can contain several 2-components, each of which can contain
one or more 3-components, and so forth.

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

flow_func : function
    Function to perform the underlying flow computations. Default value
    :meth:`edmonds_karp`. This function performs better in sparse graphs with
    right tailed degree distributions. :meth:`shortest_augmenting_path` will
    perform better in denser graphs.

Returns
-------
k_components : dict
    Dictionary with all connectivity levels `k` in the input Graph as keys
    and a list of sets of nodes that form a k-component of level `k` as
    values.

Raises
------
NetworkXNotImplemented
    If the input graph is directed.

Examples
--------
>>> # Petersen graph has 10 nodes and it is triconnected, thus all
>>> # nodes are in a single component on all three connectivity levels
>>> G = nx.petersen_graph()
>>> k_components = nx.k_components(G)

Notes
-----
Moody and White [1]_ (appendix A) provide an algorithm for identifying
k-components in a graph, which is based on Kanevsky's algorithm [2]_
for finding all minimum-size node cut-sets of a graph (implemented in
:meth:`all_node_cuts` function):

    1. Compute node connectivity, k, of the input graph G.

    2. Identify all k-cutsets at the current level of connectivity using
       Kanevsky's algorithm.

    3. Generate new graph components based on the removal of
       these cutsets. Nodes in a cutset belong to both sides
       of the induced cut.

    4. If the graph is neither complete nor trivial, return to 1;
       else end.

This implementation also uses some heuristics (see [3]_ for details)
to speed up the computation.

See also
--------
node_connectivity
all_node_cuts
biconnected_components : special case of this function when k=2
k_edge_components : similar to this function, but uses edge-connectivity
    instead of node-connectivity

References
----------
.. [1]  Moody, J. and D. White (2003). Social cohesion and embeddedness:
        A hierarchical conception of social groups.
        American Sociological Review 68(1), 103--28.
        http://www2.asanet.org/journals/ASRFeb03MoodyWhite.pdf

.. [2]  Kanevsky, A. (1993). Finding all minimum-size separating vertex
        sets in a graph. Networks 23(6), 533--541.
        http://onlinelibrary.wiley.com/doi/10.1002/net.3230230604/abstract

.. [3]  Torrents, J. and F. Ferraro (2015). Structural Cohesion:
        Visualization and Heuristics for Fast Computation.
        https://arxiv.org/pdf/1503.04476v1

      )	flow_func)kr   )r   listdefault_flow_funcnxconnected_componentssetlenappendbiconnected_componentssubgraphnode_connectivityall_node_cuts_generate_partitionnextStopIterationpop_reconstruct_k_components)Gr   r   	componentcompcbicomponentsbicomponentbicompBr   cutsstackparent_k	partitionnodesCthis_ks                     ^/var/www/html/env/lib/python3.13/site-packages/networkx/algorithms/connectivity/kcomponents.pyr   r      s   t t$L%	,,Q/	9~t9q=O""4(	 0
 ,.+D+DQ+GH+GaJJqM+GLH#[!v;?O""6*	 $
 q6Q;  8q5O""3q6*B$$QyAB(!456e$)"I!X
YJJu%--a9EH$! (//A7B,,Q&INOLL&*=av*N!OP e < %\22I I4 ! 		s   >HBHH76H7c              #   f  ^^#    [         R                  " 5       n[        [        U 5      5      mUR	                  T5        UR                  UU4S j[        TS5       5       5        [         R                  " U5       H,  n[        R                  " U Vs/ s H  nTU   PM
     sn6 v   M.     gs  snf 7f)aW  Merge sets that share k or more elements.

See: http://rosettacode.org/wiki/Set_consolidation

The iterative python implementation posted there is
faster than this because of the overhead of building a
Graph and calling nx.connected_components, but it's not
clear for us if we can use it in NetworkX because there
is no licence for the code.

c              3   b   >#    U  H$  u  p[        TU   TU   -  5      T:  d  M  X4v   M&     g 7fN)r   ).0uvr   r,   s      r/   	<genexpr>_consolidate.<locals>.<genexpr>   s5      141SqE!H9L5MQR5R1s   /
/r   N)
r   Graphdict	enumerateadd_nodes_fromadd_edges_fromr   r   r   union)setsr   r    r!   nr,   s    `   @r/   _consolidater@      s      	
A4!EU 'q1  ,,Q/	iiI6Iq%(I677 06s   BB1B,
!B1c              #   *  #    S n/ nU R                  5        VVs1 s H  u  pVXb:  d  M  UiM     snnU VVs1 s H  ow  H  oUiM     M     snn-
  nU R                  U5      n	[        R                  " U	5       Hq  n
[	        U
5      nU H-  nU H$  nU" XU
5      (       d  M  UR                  U5        M&     M/     [        U5      U R                  5       :  d  M`  UR                  U5        Ms     [        XBS-   5       S h  vN   g s  snnf s  snnf  N7f)Nc                 2   ^ [        U4S jX    5       5      $ )Nc              3   ,   >#    U  H	  oT;   v   M     g 7fr2    )r3   r?   r+   s     r/   r6   E_generate_partition.<locals>.has_nbrs_in_partition.<locals>.<genexpr>   s     37a	>7   )any)r    noder+   s     `r/   has_nbrs_in_partition2_generate_partition.<locals>.has_nbrs_in_partition   s    317333    r   )
degreer   r   r   r   addr   orderr   r@   )r    r(   r   rI   
componentsr?   dcutr,   Hccr!   rH   s                r/   r   r      s     4 J88:/:41Q:/2Rc1c12RRE	

5A%%a(G	C("55MM$'   y>AGGI%i( ) JA... 02R /s8   DDDDDAD!4D&D?D Dc                   ^ 0 n[        U 5      n[        [        SUS-   5      5       H  nX2:X  a  [        [	        X   U5      5      X'   M#  X0;  a  [        [	        XS-      U5      5      X'   MF  [
        R                  " X   6 mXS-       Vs/ s H!  n[        U4S jU 5       5      (       d  M  UPM#     nnU(       a  [        [	        X   U-   U5      5      X'   M  [        [	        X   U5      5      X'   M     U$ s  snf )Nr   c              3   ,   >#    U  H	  oT;  v   M     g 7fr2   rD   )r3   r?   
nodes_at_ks     r/   r6   ,_reconstruct_k_components.<locals>.<genexpr>   s     5USTaz6ISTrF   )maxreversedranger   r@   r   r=   rG   )k_compsresultmax_kr   r#   to_addrV   s         @r/   r   r      s    FLEeAuqy)*:\'*a89FI\&Q-;<FIGJ/J!'AVA#5UST5U2UaFV gj6.A1!EF	 gj!!<=	 + M Ws   C9-C9c                     0 n[        U R                  5       [        S5      S9 H  u  p#U H  nU H  nX!U'   M	     M     M     U$ )Nr   )key)sorteditemsr   )kcompsr\   r   compsr"   rH   s         r/   build_k_number_dictre      sF    F6<<>z!}=D t   > MrK   r2   )__doc__collectionsr   	itertoolsr   operatorr   networkxr   networkx.algorithms.flowr   networkx.utilsr   r   __all___dispatchabler   r@   r   r   re   rD   rK   r/   <module>ro      sl    $ "   2 .  
 Z F3  !F3R8,/$$rK   