
    \Mh                         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dS )z,
Moody and White algorithm for k-components
    )defaultdict)combinations)
itemgetterN)edmonds_karp)not_implemented_fork_componentsdirectedc           	          t          t                    }|t          }t          j                   D ]?}t          |          }t          |          dk    r|d                             |           @ fdt          j                   D             }|D ]?}t          |          }t          |          dk    r|d                             |           @|D ]}t          |          dk    rt          j	        ||          }	|	dk    r(||	                             t          |                     t          t          j
        ||	|                    }
|	t          ||
|	          fg}|r|d         \  }}	 t          |          }|                    |          }t          j	        ||          }||k    r.|dk    r(||                             t          |                     t          t          j
        |||                    }
|
r&|                    |t          ||
|          f           n$# t          $ r |                                 Y nw xY w|t!          |          S )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

    N   c                 :    g | ]}                     |          S  )subgraph).0cGs     l/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/networkx/algorithms/connectivity/kcomponents.py
<listcomp>z k_components.<locals>.<listcomp>x   s#    HHHaAJJqMMHHH       )	flow_func)kr   )r   listdefault_flow_funcnxconnected_componentssetlenappendbiconnected_componentsnode_connectivityall_node_cuts_generate_partitionnextr   StopIterationpop_reconstruct_k_components)r   r   r   	componentcompbicomponentsbicomponentbicompBr   cutsstackparent_k	partitionnodesCthis_ks   `                r   r   r      s{   t t$$L%	,Q// ) )	9~~t99q==O""4(((HHHH2+DQ+G+GHHHL# + +[!!v;;??O""6***  q66Q;; i888q55O""3q66***B$Q!yAAABB(D!4456 	$)"I!Xy
YJJu%%-a9EEEH$$! (//A777B,Q&INNNOO QLL&*=av*N*N!OPPP    		  	* %\222s   8B:H33IIc              #   \  K   t          j                    }t          t          |                     |                               |                    fdt          d          D                        t          j        |          D ]}t          j	        fd|D              V  dS )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   j   K   | ]-\  }}t          |         |         z            k    '||fV  .d S N)r   )r   uvr   r2   s      r   	<genexpr>z_consolidate.<locals>.<genexpr>   sT        1aSqE!H9L5M5MQR5R5RA5R5R5R5R r   r   c                      g | ]
}|         S r   r   )r   nr2   s     r   r   z _consolidate.<locals>.<listcomp>   s    666q%(666r   N)
r   Graphdict	enumerateadd_nodes_fromadd_edges_fromr   r   r   union)setsr   r   r(   r2   s    `  @r   _consolidaterD      s       	

A4!!EU     'q11      ,Q// 8 8	i6666I666777778 8r   c              #     K   d }g }fd|                                  D             d |D             z
  }|                     |          }t          j        |          D ]w}t	          |          }|D ])}	|	D ]$}
 || |
|          r|                    |
           %*t          |          |                                 k     r|                    |           xt          |dz             E d {V  d S )Nc                 F    t          fd| |         D                       S )Nc              3       K   | ]}|v V  	d S r7   r   )r   r<   r1   s     r   r:   zE_generate_partition.<locals>.has_nbrs_in_partition.<locals>.<genexpr>   s'      33a1	>333333r   any)r   noder1   s     `r   has_nbrs_in_partitionz2_generate_partition.<locals>.has_nbrs_in_partition   s*    33331T7333333r   c                 &    h | ]\  }}|k    |S r   r   )r   r<   dr   s      r   	<setcomp>z&_generate_partition.<locals>.<setcomp>   s"    ///41aQQr   c                     h | ]	}|D ]}|
S r   r   )r   cutr<   s      r   rN   z&_generate_partition.<locals>.<setcomp>   s%    2R2R2Rc2R2R12R2R2R2Rr   r   )
degreer   r   r   r   addr   orderr   rD   )r   r.   r   rK   
componentsr2   Hccr(   rP   rJ   s     `        r   r#   r#      s1     4 4 4 J////188::///2R2R2R2R2RRE	

5A%a(( ) )GG	 	( 	(C ( (((D"55 (MM$'''( y>>AGGII%%i(((JA...........r   c                     i }t          |           }t          t          d|dz                       D ]}||k    r't          t	          | |         |                    ||<   /|| vr*t          t	          ||dz            |                    ||<   ]t          j        | |          fd||dz            D             }|r*t          t	          | |         |z   |                    ||<   t          t	          | |         |                    ||<   |S )Nr   c                 J    g | ]}t          fd |D                       | S )c              3       K   | ]}|vV  	d S r7   r   )r   r<   
nodes_at_ks     r   r:   z7_reconstruct_k_components.<locals>.<listcomp>.<genexpr>   s(      5U5Uaaz6I5U5U5U5U5U5Ur   rH   )r   r   rZ   s     r   r   z-_reconstruct_k_components.<locals>.<listcomp>   s<    VVVA#5U5U5U5UST5U5U5U2U2UVaVVVr   )maxreversedranger   rD   r   rB   )k_compsresultmax_kr   to_addrZ   s        @r   r'   r'      s   FLLEeAuqy))** > >::\'!*a8899F1IIg\&Q-;;<<F1IIGAJ/JVVVVAVVVF > gaj6.A1!E!EFFq		 gaj!!<!<==q		Mr   c                     i }t          |                                 t          d                    D ]\  }}|D ]}|D ]}|||<   |S )Nr   )key)sorteditemsr   )kcompsr_   r   compsr)   rJ   s         r   build_k_number_dictrh      so    F6<<>>z!}}=== ! !5 	! 	!D ! ! t!	! Mr   r7   )__doc__collectionsr   	itertoolsr   operatorr   networkxr   networkx.algorithms.flowr   networkx.utilsr   r   __all___dispatchabler   rD   r#   r'   rh   r   r   r   <module>rr      s    $ # # # # # " " " " " "           2 1 1 1 1 1 . . . . . .  
 Z  F3 F3 F3  ! F3R8 8 8,/ / /$  $    r   