o
    h                     @   sp   d Z ddlmZ ddlZddlmZ ddlmZm	Z	m
Z
 dgZdd Ze	d	e
d
ejdddddZdS )uB   Functions for computing the Kernighan–Lin bipartition algorithm.    )countN)is_partition)
BinaryHeapnot_implemented_forpy_random_statekernighan_lin_bisectionc                 #   s    t  t  f \}} tt D ]\}}}tfdd|D } | ||r+|n|  q fdd}d}	d}
|rn|rr| \}}||| | \}}||| |
|| 7 }
|	d7 }	|
|	||ffV  |rp|s@dS dS dS dS )z
    This is a modified form of Kernighan-Lin, which moves single nodes at a
    time, alternating between sides to keep the bisection balanced.  We keep
    two min-heaps of swap costs to make optimal-next-move selection fast.
    c                 3   s&    | ]\}} | r|n| V  qd S )N ).0vw)sider   _/var/www/vscode/kcb/lib/python3.10/site-packages/networkx/algorithms/community/kernighan_lin.py	<genexpr>   s   $ z'_kernighan_lin_sweep.<locals>.<genexpr>c                    s\   | D ]'\}} |  }| |}|d ur+|d| |u r | n| 7 }|||d qd S )N   T)getinsert)costs_xxyr   costs_ycost_ycostsedgesr   r   r   _update_costs   s   
z+_kernighan_lin_sweep.<locals>._update_costsr      N)r   zipr   sumr   pop)r   r   costs0costs1uside_uedges_ucost_ur   itotcostr
   cost_vr   r   r   _kernighan_lin_sweep   s"   

r(   directed   weight)
edge_attrs
   c              
      s  t  }t }|| dd t|D |du r+dg|d  dg|d d   }n7z|\}}	W n ttfyE }
 ztd|
d}
~
ww t ||	fsRtddg| }|D ]}d|| < qY 	 rr fd	d
|D }n fdd
|D }t
|D ],}tt||}t|\}}}|dkr n|d| D ]\}}\}}d||< d||< qqdd t||D }dd t||D }	||	fS )u  Partition a graph into two blocks using the Kernighan–Lin
    algorithm.

    This algorithm partitions a network into two sets by iteratively
    swapping pairs of nodes to reduce the edge cut between the two sets.  The
    pairs are chosen according to a modified form of Kernighan-Lin [1]_, which
    moves node individually, alternating between sides to keep the bisection
    balanced.

    Parameters
    ----------
    G : NetworkX graph
        Graph must be undirected.

    partition : tuple
        Pair of iterables containing an initial partition. If not
        specified, a random balanced partition is used.

    max_iter : int
        Maximum number of times to attempt swaps to find an
        improvement before giving up.

    weight : key
        Edge data key to use as weight. If None, the weights are all
        set to one.

    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
        Only used if partition is None

    Returns
    -------
    partition : tuple
        A pair of sets of nodes representing the bipartition.

    Raises
    ------
    NetworkXError
        If partition is not a valid partition of the nodes of the graph.

    References
    ----------
    .. [1] Kernighan, B. W.; Lin, Shen (1970).
       "An efficient heuristic procedure for partitioning graphs."
       *Bell Systems Technical Journal* 49: 291--307.
       Oxford University Press 2011.

    c                 S   s   i | ]\}}||qS r   r   )r	   r%   r
   r   r   r   
<dictcomp>c   s    z+kernighan_lin_bisection.<locals>.<dictcomp>Nr   r   r   zpartition must be two setszpartition invalidc                    (   g | ]}fd d |   D qS )c                    s2   g | ]\}} | t fd d| D fqS )c                 3   s    | ]	}|  d V  qdS )r   Nr   )r	   e)r+   r   r   r   u   s    z@kernighan_lin_bisection.<locals>.<listcomp>.<listcomp>.<genexpr>)r   values)r	   r!   dindexr+   r   r   
<listcomp>t   s     6kernighan_lin_bisection.<locals>.<listcomp>.<listcomp>itemsr	   r
   Gr5   r+   r   r   r6   s   s    
z+kernighan_lin_bisection.<locals>.<listcomp>c                    r/   )c                    s$   g | ]\}} | | d fqS r   r0   )r	   r!   r1   r4   r   r   r6   |   s   $ r7   r8   r:   r;   r   r   r6   {   s    c                 S      h | ]
\}}|d kr|qS )r   r   r	   r!   sr   r   r   	<setcomp>       z*kernighan_lin_bisection.<locals>.<setcomp>c                 S   r>   r=   r   r?   r   r   r   rA      rB   )lenlistshuffle	enumerate	TypeError
ValueErrornxNetworkXErrorr   is_multigraphranger(   minr   )r<   	partitionmax_iterr+   seednlabelsr   ABerrar   r%   r   min_costmin_i_r!   r
   r   r;   r   r   +   sH   5
"


)Nr-   r+   N)__doc__	itertoolsr   networkxrI   -networkx.algorithms.community.community_utilsr   networkx.utilsr   r   r   __all__r(   _dispatchabler   r   r   r   r   <module>   s    
