
    ިsg                         d Z ddlmZ ddlmZ ddlmZ ddlZddl	m
Z
 ddlmZ e
ZdgZ ed	      ej                  dd
              Zd Zd Zd Zd Zy)z,
Moody and White algorithm for k-components
    )defaultdict)combinations)
itemgetterN)edmonds_karp)not_implemented_fork_componentsdirectedc           	      B   t        t              }|t        }t        j                  |       D ]0  }t        |      }t        |      dkD  s|d   j                  |       2 t        j                  |       D cg c]  }| j                  |       }}|D ]0  }t        |      }t        |      dkD  s|d   j                  |       2 |D ]&  }	t        |	      dk  rt        j                  |	|      }
|
dkD  r||
   j                  t        |	             t        t        j                  |	|
|            }|
t        |	||
      fg}|s|d   \  }}	 t        |      }|	j                  |      }t        j                  ||      }||kD  r"|dkD  r||   j                  t        |             t        t        j                  |||            }|r|j                  |t        |||      f       |r) t!        |      S c c}w # t        $ r |j                          Y 1w xY w)a7  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/venv/lib/python3.12/site-packages/networkx/algorithms/connectivity/kcomponents.pyr   r      s   t t$L%	,,Q/ )	9~t9q=O""4(	)
 ,.+D+DQ+GHaAJJqMHLH# +[!v;?O""6*	+
  q6Q;  i8q5O""3q6*B$$Q!yAB(D!456$)"I!Xy
YJJu%--a9EH$! (//A7B,,Q&INOLL&*=av*N!OP < %\22I I4 ! 		s   7G=BHHHc              #   T  K   t        j                         }t        t        |             |j	                         |j                  fdt        d      D               t        j                  |      D ]'  }t        j                  |D cg c]  }|   	 c}  ) yc c}w w)as  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   \   K   | ]#  \  }}t        |   |   z        k\  s||f % y wN)r   ).0uvr   r,   s      r/   	<genexpr>z_consolidate.<locals>.<genexpr>   s8      1aSqE!H9L5MQR5RA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/ 8	iiI6q%(67786s   B
B(B#
B(c              #     K   d }g }| j                         D ch c]  \  }}||kD  s| c}}|D ch c]  }|D ]  }|  c}}z
  }| j                  |      }	t        j                  |	      D ]e  }
t	        |
      }|D ]%  }|D ]  } || ||
      s|j                  |         ' t        |      | j                         k  sU|j                  |       g t        ||dz         E d {    y c c}}w c c}}w 7 w)Nc                 2    t        fd| |   D              S )Nc              3   &   K   | ]  }|v  
 y wr2    )r3   r>   r+   s     r/   r6   zE_generate_partition.<locals>.has_nbrs_in_partition.<locals>.<genexpr>   s     3a1	>3   )any)r    noder+   s     `r/   has_nbrs_in_partitionz2_generate_partition.<locals>.has_nbrs_in_partition   s    31T7333    r   )
degreer   r   r   r   addr   orderr   r?   )r    r(   r   rG   
componentsr>   dcutr,   Hccr!   rF   s                r/   r   r      s     4 J88:/41aQQ/2Rc2R12R12RRE	

5A%%a( )G	 	(C ((D"5MM$'(	( y>AGGI%i() JA... 02R /s8   C?C1C1C?C7AC?1C?%C?+C=,C?c                    i }t        |       }t        t        d|dz               D ]  }||k(  rt        t	        | |   |            ||<   $|| vrt        t	        ||dz      |            ||<   Gt        j                  | |    ||dz      D cg c]  }t        fd|D              s| }}|rt        t	        | |   |z   |            ||<   t        t	        | |   |            ||<    |S c c}w )Nr   c              3   &   K   | ]  }|v 
 y wr2   rC   )r3   r>   
nodes_at_ks     r/   r6   z,_reconstruct_k_components.<locals>.<genexpr>   s     5Uaaz6I5UrD   )maxreversedranger   r?   r   r<   rE   )k_compsresultmax_kr   r#   to_addrS   s         @r/   r   r      s    FLEeAuqy)* >:\'!*a89F1Ig\&Q-;<F1IGAJ/J!'AVA#5UST5U2UaVFV gaj6.A1!EFq	 gaj!!<=q	> M Ws   C-'C-c                     i }t        | j                         t        d            D ]  \  }}|D ]  }|D ]  }|||<   	   |S )Nr   )key)sorteditemsr   )kcompsrX   r   compsr"   rF   s         r/   build_k_number_dictra      sY    F6<<>z!}= !5 	!D ! t!	!! MrH   r2   )__doc__collectionsr   	itertoolsr   operatorr   networkxr   networkx.algorithms.flowr   networkx.utilsr   r   __all___dispatchabler   r?   r   r   ra   rC   rH   r/   <module>rk      sl    $ "   2 .  
 Z F3  !F3R8,/$$rH   