ó
    …~i–  ã                   ó¬   • 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                  " X‘S9n
U
S:”  a  X*   R                  [        U	5      5        [        [        R                  " XšUS95      nU
[        X›U
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                     Úi/home/mande/repo/quber/.venv/lib/python3.13/site-packages/networkx/algorithms/connectivity/kcomponents.pyr   r      sð  € ôt œtÓ$€LàÑÜ%ˆ	ä×,Ò,¨QÖ/ˆ	ä�9‹~ˆÜˆt‹9�q�=Ø˜‰O×"Ñ" 4Ö(ñ	 0ô
 ,.×+DÒ+DÀQÔ+GÓHÒ+G a—J‘J˜q–MÑ+G€LÐHÛ#ˆÜ�[Ó!ˆäˆv‹;˜�?Ø˜‰O×"Ñ" 6Ö*ñ	 $ô
 ˆÜˆq‹6�Q‹;ÙÜ× Ò  Ñ8ˆØˆq‹5Ø‰O×"Ñ"¤3 q£6Ô*ä”B×$Ò$ Q°yÑAÓBˆØÔ(¨°!Ó4Ð5Ð6ˆßˆeØ$)¨"¡IÑ!ˆXð
Ü˜Y›�Ø—J‘J˜uÓ%�Ü×-Ò-¨a¸9ÑE�Ø˜HÓ$¨°!«Ø  Ñ(×/Ñ/´°A³Ô7ÜœB×,Ò,¨Q°&ÀIÑNÓO�ÞØ—L‘L &Ô*=¸aÀÀvÓ*NÐ!OÔP÷ ‹eñ ô< % \Ó2Ð2ùòI 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   øé € ð Ú1‘4�1´S¸¸q¹ÀEÈ!ÁHÑ9LÓ5MÐQRÑ5R‹ˆ�Ò1ùs   ƒ/¥
/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Ö/ˆ	Ü�iŠi©IÓ6ªI q˜% œ(©IÑ6Ð7Ô7ò 0ùÚ6ùs   „BB1ÂB,
Â!B1c           
   #   ó  #   • S n/ nU VVs1 s H  oU  H  ofiM     M     nnnU R                  5        VVs1 s H  u  phX‚:”  d  M  UiM     snnU-
  n	U R                  U	5      n
[        [        [        R
                  " U
5      5       HW  nX· Vs1 s H  oc" XU5      (       d  M  UiM     sn-  n[        U5      U R                  5       :  d  MF  UR                  U5        MY     [        XBS-   5       S h  v•N   g s  snnf s  snnf s  s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   øé € Ð3ª7 a˜	–>ª7ùó   ƒ)Úany)r    Únoder+   s     `r/   Úhas_nbrs_in_partitionÚ2_generate_partition.<locals>.has_nbrs_in_partition¶   s   ø€ ÜÔ3¨1ª7Ó3Ó3Ð3ó    r   )
Údegreer   Úmapr   r   r   r   Úorderr   r@   )r    r(   r   rI   Ú
componentsÚcutr?   Ú	n_in_cutsÚdr,   ÚHÚccr!   s                r/   r   r   µ   sæ   é € ò4ð €JÙ"Ô0šd�s«C q’©C‘™d€IÑ0ØŸ8™8œ:Ô/š:‘4�1¨©�Q™:Ò/°)Ñ;€EØ	�
‰
�5Ó€AÜ”#”r×.Ò.¨qÓ1Ö2ˆØ YÓR¢Y Ð2GÈÈb×2QŸ!¡YÑRÑRˆ	Üˆy‹>˜AŸG™G›IÕ%Ø×Ñ˜iÖ(ñ 3ô ˜J¨A©Ó.×.Ñ.ùó 1ùÛ/ùò Sñ /ùsE   ‚D�C:¡D·D ÁD ÁADÂDÂ$DÂ* DÃ&DÃ4DÃ5Dc                 óø  ^• 0 nU (       a  [        U 5      OSn[        USS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   r   r   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   øé € Ð5UÒSTÈa¸zÖ6IÒSTùrF   )ÚmaxÚranger   r@   r   r=   rG   )Úk_compsÚresultÚmax_kr   r#   Úto_addrW   s         @r/   r   r   Ä   sØ   ø€ Ø€FÞ#ŒC�ŒL¨€EÜ�5˜!˜RÖ ˆØ‹:Üœ\¨'©*°aÓ8Ó9ˆF‹IØÓÜœ\¨&°Q±©-¸Ó;Ó<ˆF‹IäŸš G¡JÐ/ˆJØ!'¨A©¢ÓV¢˜A´#Ô5UÑSTÓ5U×2U—a¡ˆFÐVÞÜ ¤¨g©j¸6Ñ.AÀ1Ó!EÓF�“	ä ¤¨g©j¸!Ó!<Ó=�“	ñ !ð €Mùò Ws   Â	C7Â+C7c           
      ó®   • [        U R                  5       [        S5      S9 VVVVs0 s H  u  pU  H  nU  H  nXA_M     M     M     snnnn$ s  snnnnf )Nr   )Úkey)ÚsortedÚitemsr   )Úkcompsr   Úcompsr"   rH   s        r/   Úbuild_k_number_dictre   Ö   sZ   € ô ˜vŸ|™|›~´:¸a³=ÒAöâA‰HˆAÜˆDÜˆDð 	Šñ ñ 	áñ 	ÙAôð ùõ s   §"A
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3òR8ò,/òó$rK   