o
    ˷e                     @   sd   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
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   b/var/www/ideatree/venv/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
   weightc              
      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, which
    moves node individually, alternating between sides to keep the bisection
    balanced.

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

    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
        improvemement 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>a   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   s   s    z@kernighan_lin_bisection.<locals>.<listcomp>.<listcomp>.<genexpr>)r   values)r	   r!   dindexr,   r   r   
<listcomp>r   s     6kernighan_lin_bisection.<locals>.<listcomp>.<listcomp>itemsr	   r
   Gr4   r,   r   r   r5   q   s    
z+kernighan_lin_bisection.<locals>.<listcomp>c                    r.   )c                    s$   g | ]\}} | | d fqS r   r/   )r	   r!   r0   r3   r   r   r5   z   s   $ r6   r7   r9   r:   r   r   r5   y   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   r@      rA   )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   3
"


)Nr+   r,   N)__doc__	itertoolsr   networkxrH   -networkx.algorithms.community.community_utilsr   networkx.utilsr   r   r   __all__r(   r   r   r   r   r   <module>   s    