o
    ]Zh                     @   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   Z/var/www/auris/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)Zcosts_xxyr   Zcosts_yZcost_ycostsedgesr   r   r   _update_costs   s   
z+_kernighan_lin_sweep.<locals>._update_costsr      N)r   zipr   sumr   pop)r   r   Zcosts0Zcosts1uZside_uZedges_uZcost_ur   iZtotcostr
   Zcost_vr   r   r   _kernighan_lin_sweep   s"   

r   Zdirected   weight)Z
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
   Gr)   r    r   r   r*   s   s    
z+kernighan_lin_bisection.<locals>.<listcomp>c                    r#   )c                    s$   g | ]\}} | | d fqS r   r$   )r	   r   r%   r(   r   r   r*   |   s   $ r+   r,   r.   r/   r   r   r*   {   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   r2   r1   r   r3   r   r   r   r5      r6   )lenlistshuffle	enumerate	TypeError
ValueErrornxZNetworkXErrorr   Zis_multigraphranger   minr   )r0   	partitionZmax_iterr    seednlabelsr   ABerrar   r   r   Zmin_costZmin_i_r   r
   r   r/   r   r   +   sH   5
"


)Nr!   r    N)__doc__	itertoolsr   Znetworkxr=   Z-networkx.algorithms.community.community_utilsr   Znetworkx.utilsr   r   r   __all__r   Z_dispatchabler   r   r   r   r   <module>   s    
